oakscriptjs 0.9.0 → 0.9.2
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/dist/cjs/array/index.d.ts +1 -1
- package/dist/cjs/array/index.d.ts.map +1 -1
- package/dist/cjs/array/index.js +2 -1
- package/dist/cjs/array/index.js.map +2 -2
- package/dist/cjs/callsite/index.d.ts +27 -0
- package/dist/cjs/callsite/index.d.ts.map +1 -1
- package/dist/cjs/callsite/index.js +47 -0
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/color/index.d.ts +1 -0
- package/dist/cjs/color/index.d.ts.map +1 -1
- package/dist/cjs/color/index.js +9 -30
- package/dist/cjs/color/index.js.map +2 -2
- package/dist/cjs/color/parse.d.ts +29 -0
- package/dist/cjs/color/parse.d.ts.map +1 -0
- package/dist/cjs/color/parse.js +57 -0
- package/dist/cjs/color/parse.js.map +7 -0
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/script/index.d.ts +4 -0
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +6 -1
- package/dist/cjs/script/index.js.map +2 -2
- package/dist/cjs/ta/index.d.ts +5 -0
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +19 -19
- package/dist/cjs/ta/index.js.map +2 -2
- package/dist/esm/array/index.d.ts +1 -1
- package/dist/esm/array/index.d.ts.map +1 -1
- package/dist/esm/array/index.js +3 -2
- package/dist/esm/array/index.js.map +1 -1
- package/dist/esm/callsite/index.d.ts +27 -0
- package/dist/esm/callsite/index.d.ts.map +1 -1
- package/dist/esm/callsite/index.js +79 -0
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/color/index.d.ts +1 -0
- package/dist/esm/color/index.d.ts.map +1 -1
- package/dist/esm/color/index.js +13 -36
- package/dist/esm/color/index.js.map +1 -1
- package/dist/esm/color/parse.d.ts +29 -0
- package/dist/esm/color/parse.d.ts.map +1 -0
- package/dist/esm/color/parse.js +55 -0
- package/dist/esm/color/parse.js.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/script/index.d.ts +4 -0
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +6 -1
- package/dist/esm/script/index.js.map +1 -1
- package/dist/esm/ta/index.d.ts +5 -0
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +34 -28
- package/dist/esm/ta/index.js.map +1 -1
- package/package.json +1 -1
- package/src/array/index.ts +3 -2
- package/src/callsite/index.ts +74 -0
- package/src/color/index.ts +14 -36
- package/src/color/parse.ts +56 -0
- package/src/index.ts +1 -1
- package/src/script/index.ts +6 -1
- package/src/ta/index.ts +32 -31
|
@@ -88,7 +88,7 @@ export declare function sort<T>(id: PineArray<T>, order?: 'asc' | 'desc'): void;
|
|
|
88
88
|
*/
|
|
89
89
|
export declare function sum(id: PineArray<float>): float;
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
91
|
+
* Average of the non-na elements (PineScript `array.avg(id)`); an array without values gives NaN.
|
|
92
92
|
*/
|
|
93
93
|
export declare function avg(id: PineArray<float>): float;
|
|
94
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/array/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/array/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEpH;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAMlF;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAE7C;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAE7D;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE1E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE1C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE5C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE7E;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAEhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE5D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAE9D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAEtD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAE5E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAEtG;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,KAAK,GAAG,MAAc,GAAG,IAAI,CAQ7E;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAE/C;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAG/C;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,GAAE,UAAc,GAAG,KAAK,CAGpE;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,GAAE,UAAc,GAAG,KAAK,CAGpE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAIlD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAehD;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CAEtE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CAMzE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,GAAE,UAAc,EAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAK3G;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAEpD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE5C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE3C;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAE9C;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,IAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAE3F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,KAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAE5F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,GAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAEtF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAE1F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAEpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAEjF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAEhG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAE1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAKjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAmBnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CA0B5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CA0B7E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CAqBnG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,CAa9F;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,CAOtF;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,KAAK,CAqBnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,GAAE,KAAK,GAAG,MAAc,GAAG,SAAS,CAAC,GAAG,CAAC,CAchG;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAelE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAIhF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
package/dist/cjs/array/index.js
CHANGED
|
@@ -149,7 +149,8 @@ function sum(id) {
|
|
|
149
149
|
return id.reduce((acc, val) => acc + val, 0);
|
|
150
150
|
}
|
|
151
151
|
function avg(id) {
|
|
152
|
-
|
|
152
|
+
const values = id.filter((v) => !Number.isNaN(v));
|
|
153
|
+
return values.length ? values.reduce((a, b) => a + b, 0) / values.length : NaN;
|
|
153
154
|
}
|
|
154
155
|
function min(id, nth = 0) {
|
|
155
156
|
const values = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/array/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Array namespace\n * Mirrors PineScript's array.* functions\n */\n\nimport type { PineArray, int, float, bool, simple_int, color, Line, Box, Label, Linefill } from '../types/index.js';\n\n/**\n * Creates a new array with initial size and default value\n */\nexport function new_array<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n const arr: PineArray<T> = [];\n for (let i = 0; i < size; i++) {\n arr.push(initial_value as T);\n }\n return arr;\n}\n\n/**\n * Returns the number of elements in an array\n */\nexport function size<T>(id: PineArray<T>): int {\n return id.length;\n}\n\n/**\n * Returns the element at the specified index\n */\nexport function get<T>(id: PineArray<T>, index: simple_int): T {\n return id[index]!;\n}\n\n/**\n * Sets the value of the element at the specified index\n */\nexport function set<T>(id: PineArray<T>, index: simple_int, value: T): void {\n id[index] = value;\n}\n\n/**\n * Appends a value to the end of the array\n */\nexport function push<T>(id: PineArray<T>, value: T): void {\n id.push(value);\n}\n\n/**\n * Removes and returns the last element of the array\n */\nexport function pop<T>(id: PineArray<T>): T {\n return id.pop() as T;\n}\n\n/**\n * Inserts a value at the beginning of the array\n */\nexport function unshift<T>(id: PineArray<T>, value: T): void {\n id.unshift(value);\n}\n\n/**\n * Removes and returns the first element of the array\n */\nexport function shift<T>(id: PineArray<T>): T {\n return id.shift() as T;\n}\n\n/**\n * Removes all elements from the array\n */\nexport function clear<T>(id: PineArray<T>): void {\n id.length = 0;\n}\n\n/**\n * Inserts a value at the specified index\n */\nexport function insert<T>(id: PineArray<T>, index: simple_int, value: T): void {\n id.splice(index, 0, value);\n}\n\n/**\n * Removes the element at the specified index\n */\nexport function remove<T>(id: PineArray<T>, index: simple_int): T {\n return id.splice(index, 1)[0]!;\n}\n\n/**\n * Returns true if the array contains the value\n */\nexport function includes<T>(id: PineArray<T>, value: T): bool {\n return id.includes(value);\n}\n\n/**\n * Returns the index of the first occurrence of the value\n */\nexport function indexof<T>(id: PineArray<T>, value: T): int {\n return id.indexOf(value);\n}\n\n/**\n * Returns the index of the last occurrence of the value\n */\nexport function lastindexof<T>(id: PineArray<T>, value: T): int {\n return id.lastIndexOf(value);\n}\n\n/**\n * Returns a shallow copy of the array\n */\nexport function copy<T>(id: PineArray<T>): PineArray<T> {\n return [...id] as PineArray<T>;\n}\n\n/**\n * Concatenates two arrays\n */\nexport function concat<T>(id1: PineArray<T>, id2: PineArray<T>): PineArray<T> {\n return [...id1, ...id2] as PineArray<T>;\n}\n\n/**\n * Joins all elements into a string\n */\nexport function join(id: PineArray<any>, separator: string = ','): string {\n return id.join(separator);\n}\n\n/**\n * Reverses the array in place\n */\nexport function reverse<T>(id: PineArray<T>): void {\n id.reverse();\n}\n\n/**\n * Returns a slice of the array\n */\nexport function slice<T>(id: PineArray<T>, index_from: simple_int, index_to?: simple_int): PineArray<T> {\n return id.slice(index_from, index_to) as PineArray<T>;\n}\n\n/**\n * Sorts array elements (numeric)\n */\nexport function sort<T>(id: PineArray<T>, order: 'asc' | 'desc' = 'asc'): void {\n id.sort((a, b) => {\n if (order === 'asc') {\n return (a as any) - (b as any);\n } else {\n return (b as any) - (a as any);\n }\n });\n}\n\n/**\n * Returns the sum of all elements (numeric arrays only)\n */\nexport function sum(id: PineArray<float>): float {\n return id.reduce((acc, val) => acc + val, 0);\n}\n\n/**\n * Returns the average of all elements (numeric arrays only)\n */\nexport function avg(id: PineArray<float>): float {\n return sum(id) / size(id);\n}\n\n/**\n * The `nth` smallest value (0 = the smallest) of the non-na elements (PineScript `array.min(id, nth)`).\n * An `nth` past the end gives the greatest value; an array without values gives NaN.\n */\nexport function min(id: PineArray<float>, nth: simple_int = 0): float {\n const values = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return values.length ? values[Math.min(nth, values.length - 1)]! : NaN;\n}\n\n/**\n * The `nth` greatest value (0 = the greatest) of the non-na elements (PineScript `array.max(id, nth)`).\n * An `nth` past the end gives the smallest value; an array without values gives NaN.\n */\nexport function max(id: PineArray<float>, nth: simple_int = 0): float {\n const values = id.filter((v) => !Number.isNaN(v)).sort((a, b) => b - a);\n return values.length ? values[Math.min(nth, values.length - 1)]! : NaN;\n}\n\n/**\n * Returns the median value (numeric arrays only)\n */\nexport function median(id: PineArray<float>): float {\n const sorted = [...id].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n\n/**\n * Returns the mode (most frequent value)\n */\nexport function mode(id: PineArray<float>): float {\n const frequency: Map<float, int> = new Map();\n let maxFreq = 0;\n let mode = id[0]!;\n\n for (const val of id) {\n const freq = (frequency.get(val) || 0) + 1;\n frequency.set(val, freq);\n if (freq > maxFreq) {\n maxFreq = freq;\n mode = val;\n }\n }\n\n return mode;\n}\n\n/**\n * Standard deviation of the non-na elements (PineScript `array.stdev(id, biased)`).\n * `biased` true (default) divides by the count, false by the count - 1.\n */\nexport function stdev(id: PineArray<float>, biased: bool = true): float {\n return Math.sqrt(variance(id, biased));\n}\n\n/**\n * Variance of the non-na elements (PineScript `array.variance(id, biased)`).\n * `biased` true (default) divides by the count, false by the count - 1.\n */\nexport function variance(id: PineArray<float>, biased: bool = true): float {\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) return NaN;\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const squares = values.reduce((a, b) => a + (b - mean) * (b - mean), 0);\n return squares / (biased ? values.length : values.length - 1);\n}\n\n/**\n * Fills the array with the specified value\n */\nexport function fill<T>(id: PineArray<T>, value: T, index_from: simple_int = 0, index_to?: simple_int): void {\n const end = index_to ?? id.length;\n for (let i = index_from; i < end; i++) {\n id[i] = value;\n }\n}\n\n/**\n * Creates an array from its arguments (PineScript `array.from(arg0, arg1, ...)`).\n * `na` values are kept.\n *\n * @example\n * ```typescript\n * array.from(0.236, 0.382, 0.5, 0.618); // [0.236, 0.382, 0.5, 0.618]\n * ```\n */\nexport function from<T>(...values: T[]): PineArray<T> {\n return [...values];\n}\n\n/**\n * Returns the first element of the array\n *\n * @param id - The array\n * @returns The first element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, 0)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const firstElement = array.first(arr); // Returns: 1\n * ```\n */\nexport function first<T>(id: PineArray<T>): T {\n return id[0]!;\n}\n\n/**\n * Returns the last element of the array\n *\n * @param id - The array\n * @returns The last element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, array.size(id) - 1)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const lastElement = array.last(arr); // Returns: 5\n * ```\n */\nexport function last<T>(id: PineArray<T>): T {\n return id[id.length - 1]!;\n}\n\n/**\n * True when at least one element of a bool array is true (PineScript `array.some(id)`).\n * An empty array gives false.\n */\nexport function some(id: PineArray<bool>): bool {\n return id.some((v) => v === true);\n}\n\n/**\n * True when every element of a bool array is true (PineScript `array.every(id)`).\n * An empty array gives false, as in PineScript.\n */\nexport function every(id: PineArray<bool>): bool {\n return id.length > 0 && id.every((v) => v === true);\n}\n\n/**\n * Create new boolean array\n *\n * Creates a new array object of bool type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: false)\n * @returns New boolean array\n *\n * @example\n * ```typescript\n * const arr = array.new_bool(5, true);\n * // Creates: [true, true, true, true, true]\n * ```\n */\nexport function new_bool(size: simple_int = 0, initial_value: bool = false): PineArray<bool> {\n return new_array<bool>(size, initial_value);\n}\n\n/**\n * Create new float array\n *\n * Creates a new array object of float type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New float array\n *\n * @example\n * ```typescript\n * const arr = array.new_float(5, 0.0);\n * // Creates: [0.0, 0.0, 0.0, 0.0, 0.0]\n * ```\n */\nexport function new_float(size: simple_int = 0, initial_value: float = NaN): PineArray<float> {\n return new_array<float>(size, initial_value);\n}\n\n/**\n * Create new integer array\n *\n * Creates a new array object of int type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New integer array\n *\n * @example\n * ```typescript\n * const arr = array.new_int(5, 0);\n * // Creates: [0, 0, 0, 0, 0]\n * ```\n */\nexport function new_int(size: simple_int = 0, initial_value: int = NaN): PineArray<int> {\n return new_array<int>(size, initial_value);\n}\n\n/**\n * Create new string array\n *\n * Creates a new array object of string type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New string array\n *\n * @example\n * ```typescript\n * const arr = array.new_string(5, \"text\");\n * // Creates: [\"text\", \"text\", \"text\", \"text\", \"text\"]\n * ```\n */\nexport function new_string(size: simple_int = 0, initial_value?: string): PineArray<string> {\n return new_array<string>(size, initial_value);\n}\n\n/**\n * Create new color array\n *\n * Creates a new array object of color type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New color array\n *\n * @example\n * ```typescript\n * const arr = array.new_color(5, \"#FF0000\");\n * // Creates: [\"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\"]\n * ```\n */\nexport function new_color(size: simple_int = 0, initial_value?: color): PineArray<color> {\n return new_array<color>(size, initial_value);\n}\n\n/**\n * Create new line array\n *\n * Creates a new array object of line type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New line array\n *\n * @example\n * ```typescript\n * import { array, line } from 'oakscriptjs';\n *\n * // Create array to store last 15 lines\n * const lines = array.new_line();\n * const trendLine = line.new(0, 100, 50, 150);\n * array.push(lines, trendLine);\n *\n * // Manage line count\n * if (array.size(lines) > 15) {\n * const oldLine = array.shift(lines);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of trend lines, support/resistance levels, or channel lines.\n * In PineScript, this is typically used with line.delete() to manage chart object limits.\n */\nexport function new_line(size: simple_int = 0, initial_value?: Line): PineArray<Line> {\n return new_array<Line>(size, initial_value);\n}\n\n/**\n * Create new box array\n *\n * Creates a new array object of box type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New box array\n *\n * @example\n * ```typescript\n * import { array, box } from 'oakscriptjs';\n *\n * // Create array to store gap boxes\n * const gaps = array.new_box();\n * const gapBox = box.new(10, 120, 15, 110);\n * array.push(gaps, gapBox);\n *\n * // Track multiple gaps\n * for (let i = 0; i < array.size(gaps); i++) {\n * const gap = array.get(gaps, i);\n * const gapTop = box.get_top(gap);\n * const gapBottom = box.get_bottom(gap);\n * // Check if gap filled...\n * }\n * ```\n *\n * @remarks\n * Useful for tracking ranges, gaps, consolidation zones, or rectangle patterns.\n * Enables systematic analysis of multiple box objects.\n */\nexport function new_box(size: simple_int = 0, initial_value?: Box): PineArray<Box> {\n return new_array<Box>(size, initial_value);\n}\n\n/**\n * Create new label array\n *\n * Creates a new array object of label type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New label array\n *\n * @example\n * ```typescript\n * import { array, label } from 'oakscriptjs';\n *\n * // Create array to store pivot labels\n * const pivotLabels = array.new_label();\n *\n * // Add labels for pivot highs\n * const pivotLabel = label.new(50, 155.5, 'PH', 'bar_index', 'abovebar');\n * array.push(pivotLabels, pivotLabel);\n *\n * // Limit number of labels shown\n * const maxLabels = 50;\n * if (array.size(pivotLabels) > maxLabels) {\n * array.shift(pivotLabels);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of annotations, pivot markers, or signal labels.\n * Helps limit the number of labels displayed by removing old ones.\n */\nexport function new_label(size: simple_int = 0, initial_value?: Label): PineArray<Label> {\n return new_array<Label>(size, initial_value);\n}\n\n/**\n * Create new linefill array\n *\n * Creates a new array object of linefill type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New linefill array\n *\n * @example\n * ```typescript\n * import { array, line, linefill } from 'oakscriptjs';\n *\n * // Create array to store channel fills\n * const channels = array.new_linefill();\n *\n * // Create channel\n * const upperLine = line.new(0, 120, 50, 130);\n * const lowerLine = line.new(0, 100, 50, 110);\n * const channelFill = linefill.new(upperLine, lowerLine, '#0000FF15');\n *\n * array.push(channels, channelFill);\n * ```\n *\n * @remarks\n * Useful for managing collections of channel fills, Bollinger Band fills, or regression channel fills.\n * Enables dynamic color changes across multiple channels.\n */\nexport function new_linefill(size: simple_int = 0, initial_value?: Linefill): PineArray<Linefill> {\n return new_array<Linefill>(size, initial_value);\n}\n\n/**\n * Absolute value of array elements\n *\n * Returns an array containing the absolute value of each element in the original array.\n *\n * @param id - Array of numeric values\n * @returns New array with absolute values\n *\n * @example\n * ```typescript\n * const arr = [-1, -2, 3, -4, 5];\n * const result = array.abs(arr);\n * // Returns: [1, 2, 3, 4, 5]\n * ```\n */\nexport function abs(id: PineArray<float>): PineArray<float> {\n return id.map(x => Math.abs(x)) as PineArray<float>;\n}\n\n/**\n * Range of array values\n *\n * Returns the difference between the maximum and minimum values in the array.\n *\n * @param id - Array of numeric values\n * @returns Difference between max and min (range)\n *\n * @example\n * ```typescript\n * const arr = [1, 5, 3, 9, 2];\n * const result = array.range(arr);\n * // Returns: 8 (9 - 1)\n * ```\n *\n * @remarks\n * Returns NaN if the array is empty.\n */\nexport function range(id: PineArray<float>): float {\n if (id.length === 0) {\n return NaN;\n }\n return max(id) - min(id);\n}\n\n/**\n * Binary Search\n *\n * Searches for a value in a sorted array using binary search algorithm.\n * Returns the index of the value if found, or -1 if not found.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of the value, or -1 if not found\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9]; // Must be sorted\n * const index = array.binary_search(arr, 5);\n * // Returns: 3\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - Uses standard binary search algorithm\n * - Time complexity: O(log n)\n */\nexport function binary_search(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! === val) {\n return mid;\n }\n\n if (id[mid]! < val) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return -1; // Not found\n}\n\n/**\n * Binary Search Leftmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the next smallest element to the left of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the left\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_leftmost(arr, 3);\n * // Returns: 2 (index of 1, which is left of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_leftmost(arr, 5);\n * // Returns: 1 (index of first instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns leftmost occurrence\n * - When value not found, returns position of next smaller element\n */\nexport function binary_search_leftmost(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n let result = -1;\n let found = false;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! < val) {\n if (!found) {\n result = mid; // Track the last element smaller than val (only if not found)\n }\n left = mid + 1;\n } else if (id[mid]! === val) {\n result = mid;\n found = true;\n // Continue searching to the left for leftmost occurrence\n right = mid - 1;\n } else {\n // id[mid] > val\n right = mid - 1;\n }\n }\n\n return result;\n}\n\n/**\n * Binary Search Rightmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the element to the right of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the right\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_rightmost(arr, 3);\n * // Returns: 3 (index of 5, which is right of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_rightmost(arr, 5);\n * // Returns: 3 (index of last instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns rightmost occurrence\n * - When value not found, returns position of next larger element\n */\nexport function binary_search_rightmost(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n let result = -1;\n let found = false;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! <= val) {\n if (id[mid]! === val) {\n result = mid;\n found = true;\n }\n // Continue searching to the right for rightmost occurrence\n left = mid + 1;\n } else {\n // id[mid] > val\n if (!found) {\n result = mid; // Track the first element greater than val (only if not found)\n }\n right = mid - 1;\n }\n }\n\n return result;\n}\n\n/**\n * Covariance\n *\n * Returns the covariance between two arrays.\n *\n * @param id1 - First array\n * @param id2 - Second array\n * @param biased - If true, uses biased estimate (population). If false, uses unbiased estimate (sample). Default: true\n * @returns Covariance between the two arrays\n *\n * @example\n * ```typescript\n * const prices = [100, 102, 98, 105, 103];\n * const volume = [1000, 1200, 950, 1300, 1100];\n * const cov = array.covariance(prices, volume);\n * // Returns covariance between price and volume\n * ```\n *\n * @remarks\n * - Biased (true): divides by n (population covariance)\n * - Unbiased (false): divides by n-1 (sample covariance)\n * - Returns NaN if arrays are empty or have different lengths\n * - Formula: Cov(X,Y) = E[(X - \u03BCX)(Y - \u03BCY)]\n */\nexport function covariance(id1: PineArray<float>, id2: PineArray<float>, biased: bool = true): float {\n if (id1.length === 0 || id2.length === 0) {\n return NaN;\n }\n\n if (id1.length !== id2.length) {\n return NaN;\n }\n\n const n = id1.length;\n const mean1 = avg(id1);\n const mean2 = avg(id2);\n\n let sum = 0;\n for (let i = 0; i < n; i++) {\n sum += (id1[i]! - mean1) * (id2[i]! - mean2);\n }\n\n // Biased: divide by n, Unbiased: divide by n-1\n const divisor = biased ? n : n - 1;\n return sum / divisor;\n}\n\n/**\n * Percentile Linear Interpolation\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using linear interpolation.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using linear interpolation\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_linear_interpolation(arr, 50);\n * // Returns: 3 (median)\n * ```\n *\n * @remarks\n * - Uses linear interpolation between adjacent values\n * - Result may not be a member of the array\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - position in the sorted array: `percentage / 100 * size - 0.5`, clamped to the first / last value, linear\n * interpolation between the two neighbours\n * - `na` values are sorted after all numbers; with an `na` in the array, a position between two values gives `na`\n */\nexport function percentile_linear_interpolation(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const s = sortedNaLast(id);\n const n = s.length;\n const pos = (percentage / 100) * n - 0.5;\n if (pos <= 0) return s[0]!;\n if (pos >= n - 1) return s[n - 1]!;\n const lo = Math.floor(pos);\n const f = pos - lo;\n if (f === 0) return s[lo]!;\n return Number.isNaN(s[n - 1]!) ? NaN : s[lo]! + f * (s[lo + 1]! - s[lo]!);\n}\n\n/** Array values sorted ascending, `na` values after the numbers (array.percentile_*). */\nfunction sortedNaLast(id: PineArray<float>): number[] {\n const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return [...numbers, ...Array<number>(id.length - numbers.length).fill(NaN)];\n}\n\n/**\n * Percentile Nearest Rank\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using the nearest-rank method.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using nearest rank\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_nearest_rank(arr, 50);\n * // Returns: 3 (median, always a member of array)\n * ```\n *\n * @remarks\n * - Result is always a member of the array\n * - Uses nearest-rank method (no interpolation)\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - the value at rank `ceil(percentage / 100 * size)` of the sorted array\n * - `na` values are sorted after all numbers (na when that rank holds an `na`)\n */\nexport function percentile_nearest_rank(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const s = sortedNaLast(id);\n const rank = Math.min(s.length, Math.max(1, Math.ceil((percentage / 100) * s.length)));\n return s[rank - 1]!;\n}\n\n/**\n * Percent Rank\n *\n * Returns the percentile rank of the element at the specified index.\n * The percentile rank is the percentage of elements that are less than\n * or equal to the reference value.\n *\n * @param id - Array of numeric values\n * @param index - Index of element to rank\n * @returns Percentile rank (0-100)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const rank = array.percentrank(arr, 2); // Value at index 2 is 3\n * // Returns: 40 (40% of values <= 3)\n * ```\n *\n * @remarks\n * - Returns percentage of elements <= the value at given index\n * - Range: 0 to 100\n * - Returns NaN if array is empty or index out of bounds\n */\nexport function percentrank(id: PineArray<float>, index: int): float {\n if (id.length === 0 || index < 0 || index >= id.length) {\n return NaN;\n }\n\n const value = id[index]!;\n\n if (isNaN(value)) {\n return NaN;\n }\n\n // Count elements less than or equal to the value\n let count = 0;\n for (let i = 0; i < id.length; i++) {\n if (!isNaN(id[i]!) && id[i]! <= value) {\n count++;\n }\n }\n\n // Calculate percentage\n return (count / id.length) * 100;\n}\n\n/**\n * Sort Indices\n *\n * Returns an array of indices which, when used to index the original array,\n * will access its elements in their sorted order. Does not modify the original array.\n *\n * @param id - Array to get sorted indices from\n * @param order - Sort order: 'asc' or 'desc' (default: 'asc')\n * @returns Array of indices in sorted order\n *\n * @example\n * ```typescript\n * const arr = [5, -2, 0, 9, 1];\n * const indices = array.sort_indices(arr); // [1, 2, 4, 0, 3]\n * // arr[1] = -2 (smallest)\n * // arr[2] = 0\n * // arr[4] = 1\n * // arr[0] = 5\n * // arr[3] = 9 (largest)\n * ```\n *\n * @remarks\n * - Original array is not modified\n * - Returns indices that would sort the array\n * - Useful for maintaining correspondence with other arrays\n */\nexport function sort_indices(id: PineArray<float>, order: 'asc' | 'desc' = 'asc'): PineArray<int> {\n // Create array of indices\n const indices: PineArray<int> = Array.from({ length: id.length }, (_, i) => i) as PineArray<int>;\n\n // Sort indices based on values in original array\n indices.sort((a, b) => {\n if (order === 'asc') {\n return id[a]! - id[b]!;\n } else {\n return id[b]! - id[a]!;\n }\n });\n\n return indices;\n}\n\n/**\n * Standardize\n *\n * Returns an array of standardized elements (z-score normalization).\n * Each element is transformed to (value - mean) / stddev.\n *\n * @param id - Array of numeric values\n * @returns Array of standardized values (z-scores)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const standardized = array.standardize(arr);\n * // Mean = 3, StdDev \u2248 1.414\n * // Result \u2248 [-1.414, -0.707, 0, 0.707, 1.414]\n * ```\n *\n * @remarks\n * - Formula: z = (x - \u03BC) / \u03C3\n * - Result has mean of 0 and standard deviation of 1\n * - Returns array of NaN if standard deviation is 0\n * - Useful for comparing values on different scales\n */\nexport function standardize(id: PineArray<float>): PineArray<float> {\n if (id.length === 0) {\n return [] as PineArray<float>;\n }\n\n const mean = avg(id);\n const stdDev = stdev(id);\n\n // If stddev is 0, all values are the same - return array of 0s or NaN\n if (stdDev === 0) {\n return id.map(() => NaN) as PineArray<float>;\n }\n\n // Calculate z-score for each element\n return id.map(value => (value - mean) / stdDev) as PineArray<float>;\n}\n\n/**\n * New Type (User-Defined Type Array)\n *\n * Creates a new array of user-defined type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements\n * @returns New array of user-defined type\n *\n * @example\n * ```typescript\n * // NOTE: User-defined types (UDTs) are not fully supported yet\n * // This is a placeholder for future implementation\n * const arr = array.newtype<MyType>(5);\n * ```\n *\n * @remarks\n * - **\u26A0\uFE0F LIMITED SUPPORT**: User-defined types (UDTs) require a type system\n * that is not yet fully implemented in this library\n * - This function currently works like `new_array<T>()` for basic types\n * - Full UDT support will be added in a future version\n * - See PineScript documentation for UDT usage patterns\n */\nexport function newtype<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n // For now, this is just an alias for new_array\n // Full UDT support requires implementing the type system\n return new_array<T>(size, initial_value);\n}\n\n/**\n * \u26A0\uFE0F RENDERING FUNCTIONS NOT IMPLEMENTED\n *\n * The following array constructor functions are intentionally excluded\n * because they create arrays for rendering objects, which are outside\n * the scope of this calculation-focused library:\n *\n * - `new_box()` - Creates arrays of box drawing objects\n * - `new_label()` - Creates arrays of label objects\n * - `new_line()` - Creates arrays of line drawing objects\n * - `new_linefill()` - Creates arrays of line fill objects\n * - `new_table()` - Creates arrays of table layout objects\n *\n * **Design Constraint**: This library focuses on calculation and indicator\n * functions only. Rendering, visualization, and UI functions require a\n * rendering engine and are not included.\n *\n * If you need these functions, consider:\n * 1. Using PineScript directly\n * 2. Implementing a rendering layer separately\n * 3. Using this library for calculations and another library for visualization\n */\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,UAAaA,QAAmB,GAAG,eAAiC;AAClF,QAAM,MAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAIA,OAAM,KAAK;AAC7B,QAAI,KAAK,aAAkB;AAAA,EAC7B;AACA,SAAO;AACT;AAKO,SAAS,KAAQ,IAAuB;AAC7C,SAAO,GAAG;AACZ;AAKO,SAAS,IAAO,IAAkB,OAAsB;AAC7D,SAAO,GAAG,KAAK;AACjB;AAKO,SAAS,IAAO,IAAkB,OAAmB,OAAgB;AAC1E,KAAG,KAAK,IAAI;AACd;AAKO,SAAS,KAAQ,IAAkB,OAAgB;AACxD,KAAG,KAAK,KAAK;AACf;AAKO,SAAS,IAAO,IAAqB;AAC1C,SAAO,GAAG,IAAI;AAChB;AAKO,SAAS,QAAW,IAAkB,OAAgB;AAC3D,KAAG,QAAQ,KAAK;AAClB;AAKO,SAAS,MAAS,IAAqB;AAC5C,SAAO,GAAG,MAAM;AAClB;AAKO,SAAS,MAAS,IAAwB;AAC/C,KAAG,SAAS;AACd;AAKO,SAAS,OAAU,IAAkB,OAAmB,OAAgB;AAC7E,KAAG,OAAO,OAAO,GAAG,KAAK;AAC3B;AAKO,SAAS,OAAU,IAAkB,OAAsB;AAChE,SAAO,GAAG,OAAO,OAAO,CAAC,EAAE,CAAC;AAC9B;AAKO,SAAS,SAAY,IAAkB,OAAgB;AAC5D,SAAO,GAAG,SAAS,KAAK;AAC1B;AAKO,SAAS,QAAW,IAAkB,OAAe;AAC1D,SAAO,GAAG,QAAQ,KAAK;AACzB;AAKO,SAAS,YAAe,IAAkB,OAAe;AAC9D,SAAO,GAAG,YAAY,KAAK;AAC7B;AAKO,SAAS,KAAQ,IAAgC;AACtD,SAAO,CAAC,GAAG,EAAE;AACf;AAKO,SAAS,OAAU,KAAmB,KAAiC;AAC5E,SAAO,CAAC,GAAG,KAAK,GAAG,GAAG;AACxB;AAKO,SAAS,KAAK,IAAoB,YAAoB,KAAa;AACxE,SAAO,GAAG,KAAK,SAAS;AAC1B;AAKO,SAAS,QAAW,IAAwB;AACjD,KAAG,QAAQ;AACb;AAKO,SAAS,MAAS,IAAkB,YAAwB,UAAqC;AACtG,SAAO,GAAG,MAAM,YAAY,QAAQ;AACtC;AAKO,SAAS,KAAQ,IAAkB,QAAwB,OAAa;AAC7E,KAAG,KAAK,CAAC,GAAG,MAAM;AAChB,QAAI,UAAU,OAAO;AACnB,aAAQ,IAAa;AAAA,IACvB,OAAO;AACL,aAAQ,IAAa;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAKO,SAAS,IAAI,IAA6B;AAC/C,SAAO,GAAG,OAAO,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC;AAC7C;AAKO,SAAS,IAAI,IAA6B;AAC/C,SAAO,IAAI,
|
|
4
|
+
"sourcesContent": ["/**\n * Array namespace\n * Mirrors PineScript's array.* functions\n */\n\nimport type { PineArray, int, float, bool, simple_int, color, Line, Box, Label, Linefill } from '../types/index.js';\n\n/**\n * Creates a new array with initial size and default value\n */\nexport function new_array<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n const arr: PineArray<T> = [];\n for (let i = 0; i < size; i++) {\n arr.push(initial_value as T);\n }\n return arr;\n}\n\n/**\n * Returns the number of elements in an array\n */\nexport function size<T>(id: PineArray<T>): int {\n return id.length;\n}\n\n/**\n * Returns the element at the specified index\n */\nexport function get<T>(id: PineArray<T>, index: simple_int): T {\n return id[index]!;\n}\n\n/**\n * Sets the value of the element at the specified index\n */\nexport function set<T>(id: PineArray<T>, index: simple_int, value: T): void {\n id[index] = value;\n}\n\n/**\n * Appends a value to the end of the array\n */\nexport function push<T>(id: PineArray<T>, value: T): void {\n id.push(value);\n}\n\n/**\n * Removes and returns the last element of the array\n */\nexport function pop<T>(id: PineArray<T>): T {\n return id.pop() as T;\n}\n\n/**\n * Inserts a value at the beginning of the array\n */\nexport function unshift<T>(id: PineArray<T>, value: T): void {\n id.unshift(value);\n}\n\n/**\n * Removes and returns the first element of the array\n */\nexport function shift<T>(id: PineArray<T>): T {\n return id.shift() as T;\n}\n\n/**\n * Removes all elements from the array\n */\nexport function clear<T>(id: PineArray<T>): void {\n id.length = 0;\n}\n\n/**\n * Inserts a value at the specified index\n */\nexport function insert<T>(id: PineArray<T>, index: simple_int, value: T): void {\n id.splice(index, 0, value);\n}\n\n/**\n * Removes the element at the specified index\n */\nexport function remove<T>(id: PineArray<T>, index: simple_int): T {\n return id.splice(index, 1)[0]!;\n}\n\n/**\n * Returns true if the array contains the value\n */\nexport function includes<T>(id: PineArray<T>, value: T): bool {\n return id.includes(value);\n}\n\n/**\n * Returns the index of the first occurrence of the value\n */\nexport function indexof<T>(id: PineArray<T>, value: T): int {\n return id.indexOf(value);\n}\n\n/**\n * Returns the index of the last occurrence of the value\n */\nexport function lastindexof<T>(id: PineArray<T>, value: T): int {\n return id.lastIndexOf(value);\n}\n\n/**\n * Returns a shallow copy of the array\n */\nexport function copy<T>(id: PineArray<T>): PineArray<T> {\n return [...id] as PineArray<T>;\n}\n\n/**\n * Concatenates two arrays\n */\nexport function concat<T>(id1: PineArray<T>, id2: PineArray<T>): PineArray<T> {\n return [...id1, ...id2] as PineArray<T>;\n}\n\n/**\n * Joins all elements into a string\n */\nexport function join(id: PineArray<any>, separator: string = ','): string {\n return id.join(separator);\n}\n\n/**\n * Reverses the array in place\n */\nexport function reverse<T>(id: PineArray<T>): void {\n id.reverse();\n}\n\n/**\n * Returns a slice of the array\n */\nexport function slice<T>(id: PineArray<T>, index_from: simple_int, index_to?: simple_int): PineArray<T> {\n return id.slice(index_from, index_to) as PineArray<T>;\n}\n\n/**\n * Sorts array elements (numeric)\n */\nexport function sort<T>(id: PineArray<T>, order: 'asc' | 'desc' = 'asc'): void {\n id.sort((a, b) => {\n if (order === 'asc') {\n return (a as any) - (b as any);\n } else {\n return (b as any) - (a as any);\n }\n });\n}\n\n/**\n * Returns the sum of all elements (numeric arrays only)\n */\nexport function sum(id: PineArray<float>): float {\n return id.reduce((acc, val) => acc + val, 0);\n}\n\n/**\n * Average of the non-na elements (PineScript `array.avg(id)`); an array without values gives NaN.\n */\nexport function avg(id: PineArray<float>): float {\n const values = id.filter((v) => !Number.isNaN(v));\n return values.length ? values.reduce((a, b) => a + b, 0) / values.length : NaN;\n}\n\n/**\n * The `nth` smallest value (0 = the smallest) of the non-na elements (PineScript `array.min(id, nth)`).\n * An `nth` past the end gives the greatest value; an array without values gives NaN.\n */\nexport function min(id: PineArray<float>, nth: simple_int = 0): float {\n const values = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return values.length ? values[Math.min(nth, values.length - 1)]! : NaN;\n}\n\n/**\n * The `nth` greatest value (0 = the greatest) of the non-na elements (PineScript `array.max(id, nth)`).\n * An `nth` past the end gives the smallest value; an array without values gives NaN.\n */\nexport function max(id: PineArray<float>, nth: simple_int = 0): float {\n const values = id.filter((v) => !Number.isNaN(v)).sort((a, b) => b - a);\n return values.length ? values[Math.min(nth, values.length - 1)]! : NaN;\n}\n\n/**\n * Returns the median value (numeric arrays only)\n */\nexport function median(id: PineArray<float>): float {\n const sorted = [...id].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n\n/**\n * Returns the mode (most frequent value)\n */\nexport function mode(id: PineArray<float>): float {\n const frequency: Map<float, int> = new Map();\n let maxFreq = 0;\n let mode = id[0]!;\n\n for (const val of id) {\n const freq = (frequency.get(val) || 0) + 1;\n frequency.set(val, freq);\n if (freq > maxFreq) {\n maxFreq = freq;\n mode = val;\n }\n }\n\n return mode;\n}\n\n/**\n * Standard deviation of the non-na elements (PineScript `array.stdev(id, biased)`).\n * `biased` true (default) divides by the count, false by the count - 1.\n */\nexport function stdev(id: PineArray<float>, biased: bool = true): float {\n return Math.sqrt(variance(id, biased));\n}\n\n/**\n * Variance of the non-na elements (PineScript `array.variance(id, biased)`).\n * `biased` true (default) divides by the count, false by the count - 1.\n */\nexport function variance(id: PineArray<float>, biased: bool = true): float {\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) return NaN;\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const squares = values.reduce((a, b) => a + (b - mean) * (b - mean), 0);\n return squares / (biased ? values.length : values.length - 1);\n}\n\n/**\n * Fills the array with the specified value\n */\nexport function fill<T>(id: PineArray<T>, value: T, index_from: simple_int = 0, index_to?: simple_int): void {\n const end = index_to ?? id.length;\n for (let i = index_from; i < end; i++) {\n id[i] = value;\n }\n}\n\n/**\n * Creates an array from its arguments (PineScript `array.from(arg0, arg1, ...)`).\n * `na` values are kept.\n *\n * @example\n * ```typescript\n * array.from(0.236, 0.382, 0.5, 0.618); // [0.236, 0.382, 0.5, 0.618]\n * ```\n */\nexport function from<T>(...values: T[]): PineArray<T> {\n return [...values];\n}\n\n/**\n * Returns the first element of the array\n *\n * @param id - The array\n * @returns The first element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, 0)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const firstElement = array.first(arr); // Returns: 1\n * ```\n */\nexport function first<T>(id: PineArray<T>): T {\n return id[0]!;\n}\n\n/**\n * Returns the last element of the array\n *\n * @param id - The array\n * @returns The last element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, array.size(id) - 1)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const lastElement = array.last(arr); // Returns: 5\n * ```\n */\nexport function last<T>(id: PineArray<T>): T {\n return id[id.length - 1]!;\n}\n\n/**\n * True when at least one element of a bool array is true (PineScript `array.some(id)`).\n * An empty array gives false.\n */\nexport function some(id: PineArray<bool>): bool {\n return id.some((v) => v === true);\n}\n\n/**\n * True when every element of a bool array is true (PineScript `array.every(id)`).\n * An empty array gives false, as in PineScript.\n */\nexport function every(id: PineArray<bool>): bool {\n return id.length > 0 && id.every((v) => v === true);\n}\n\n/**\n * Create new boolean array\n *\n * Creates a new array object of bool type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: false)\n * @returns New boolean array\n *\n * @example\n * ```typescript\n * const arr = array.new_bool(5, true);\n * // Creates: [true, true, true, true, true]\n * ```\n */\nexport function new_bool(size: simple_int = 0, initial_value: bool = false): PineArray<bool> {\n return new_array<bool>(size, initial_value);\n}\n\n/**\n * Create new float array\n *\n * Creates a new array object of float type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New float array\n *\n * @example\n * ```typescript\n * const arr = array.new_float(5, 0.0);\n * // Creates: [0.0, 0.0, 0.0, 0.0, 0.0]\n * ```\n */\nexport function new_float(size: simple_int = 0, initial_value: float = NaN): PineArray<float> {\n return new_array<float>(size, initial_value);\n}\n\n/**\n * Create new integer array\n *\n * Creates a new array object of int type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New integer array\n *\n * @example\n * ```typescript\n * const arr = array.new_int(5, 0);\n * // Creates: [0, 0, 0, 0, 0]\n * ```\n */\nexport function new_int(size: simple_int = 0, initial_value: int = NaN): PineArray<int> {\n return new_array<int>(size, initial_value);\n}\n\n/**\n * Create new string array\n *\n * Creates a new array object of string type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New string array\n *\n * @example\n * ```typescript\n * const arr = array.new_string(5, \"text\");\n * // Creates: [\"text\", \"text\", \"text\", \"text\", \"text\"]\n * ```\n */\nexport function new_string(size: simple_int = 0, initial_value?: string): PineArray<string> {\n return new_array<string>(size, initial_value);\n}\n\n/**\n * Create new color array\n *\n * Creates a new array object of color type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New color array\n *\n * @example\n * ```typescript\n * const arr = array.new_color(5, \"#FF0000\");\n * // Creates: [\"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\"]\n * ```\n */\nexport function new_color(size: simple_int = 0, initial_value?: color): PineArray<color> {\n return new_array<color>(size, initial_value);\n}\n\n/**\n * Create new line array\n *\n * Creates a new array object of line type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New line array\n *\n * @example\n * ```typescript\n * import { array, line } from 'oakscriptjs';\n *\n * // Create array to store last 15 lines\n * const lines = array.new_line();\n * const trendLine = line.new(0, 100, 50, 150);\n * array.push(lines, trendLine);\n *\n * // Manage line count\n * if (array.size(lines) > 15) {\n * const oldLine = array.shift(lines);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of trend lines, support/resistance levels, or channel lines.\n * In PineScript, this is typically used with line.delete() to manage chart object limits.\n */\nexport function new_line(size: simple_int = 0, initial_value?: Line): PineArray<Line> {\n return new_array<Line>(size, initial_value);\n}\n\n/**\n * Create new box array\n *\n * Creates a new array object of box type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New box array\n *\n * @example\n * ```typescript\n * import { array, box } from 'oakscriptjs';\n *\n * // Create array to store gap boxes\n * const gaps = array.new_box();\n * const gapBox = box.new(10, 120, 15, 110);\n * array.push(gaps, gapBox);\n *\n * // Track multiple gaps\n * for (let i = 0; i < array.size(gaps); i++) {\n * const gap = array.get(gaps, i);\n * const gapTop = box.get_top(gap);\n * const gapBottom = box.get_bottom(gap);\n * // Check if gap filled...\n * }\n * ```\n *\n * @remarks\n * Useful for tracking ranges, gaps, consolidation zones, or rectangle patterns.\n * Enables systematic analysis of multiple box objects.\n */\nexport function new_box(size: simple_int = 0, initial_value?: Box): PineArray<Box> {\n return new_array<Box>(size, initial_value);\n}\n\n/**\n * Create new label array\n *\n * Creates a new array object of label type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New label array\n *\n * @example\n * ```typescript\n * import { array, label } from 'oakscriptjs';\n *\n * // Create array to store pivot labels\n * const pivotLabels = array.new_label();\n *\n * // Add labels for pivot highs\n * const pivotLabel = label.new(50, 155.5, 'PH', 'bar_index', 'abovebar');\n * array.push(pivotLabels, pivotLabel);\n *\n * // Limit number of labels shown\n * const maxLabels = 50;\n * if (array.size(pivotLabels) > maxLabels) {\n * array.shift(pivotLabels);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of annotations, pivot markers, or signal labels.\n * Helps limit the number of labels displayed by removing old ones.\n */\nexport function new_label(size: simple_int = 0, initial_value?: Label): PineArray<Label> {\n return new_array<Label>(size, initial_value);\n}\n\n/**\n * Create new linefill array\n *\n * Creates a new array object of linefill type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New linefill array\n *\n * @example\n * ```typescript\n * import { array, line, linefill } from 'oakscriptjs';\n *\n * // Create array to store channel fills\n * const channels = array.new_linefill();\n *\n * // Create channel\n * const upperLine = line.new(0, 120, 50, 130);\n * const lowerLine = line.new(0, 100, 50, 110);\n * const channelFill = linefill.new(upperLine, lowerLine, '#0000FF15');\n *\n * array.push(channels, channelFill);\n * ```\n *\n * @remarks\n * Useful for managing collections of channel fills, Bollinger Band fills, or regression channel fills.\n * Enables dynamic color changes across multiple channels.\n */\nexport function new_linefill(size: simple_int = 0, initial_value?: Linefill): PineArray<Linefill> {\n return new_array<Linefill>(size, initial_value);\n}\n\n/**\n * Absolute value of array elements\n *\n * Returns an array containing the absolute value of each element in the original array.\n *\n * @param id - Array of numeric values\n * @returns New array with absolute values\n *\n * @example\n * ```typescript\n * const arr = [-1, -2, 3, -4, 5];\n * const result = array.abs(arr);\n * // Returns: [1, 2, 3, 4, 5]\n * ```\n */\nexport function abs(id: PineArray<float>): PineArray<float> {\n return id.map(x => Math.abs(x)) as PineArray<float>;\n}\n\n/**\n * Range of array values\n *\n * Returns the difference between the maximum and minimum values in the array.\n *\n * @param id - Array of numeric values\n * @returns Difference between max and min (range)\n *\n * @example\n * ```typescript\n * const arr = [1, 5, 3, 9, 2];\n * const result = array.range(arr);\n * // Returns: 8 (9 - 1)\n * ```\n *\n * @remarks\n * Returns NaN if the array is empty.\n */\nexport function range(id: PineArray<float>): float {\n if (id.length === 0) {\n return NaN;\n }\n return max(id) - min(id);\n}\n\n/**\n * Binary Search\n *\n * Searches for a value in a sorted array using binary search algorithm.\n * Returns the index of the value if found, or -1 if not found.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of the value, or -1 if not found\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9]; // Must be sorted\n * const index = array.binary_search(arr, 5);\n * // Returns: 3\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - Uses standard binary search algorithm\n * - Time complexity: O(log n)\n */\nexport function binary_search(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! === val) {\n return mid;\n }\n\n if (id[mid]! < val) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return -1; // Not found\n}\n\n/**\n * Binary Search Leftmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the next smallest element to the left of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the left\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_leftmost(arr, 3);\n * // Returns: 2 (index of 1, which is left of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_leftmost(arr, 5);\n * // Returns: 1 (index of first instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns leftmost occurrence\n * - When value not found, returns position of next smaller element\n */\nexport function binary_search_leftmost(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n let result = -1;\n let found = false;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! < val) {\n if (!found) {\n result = mid; // Track the last element smaller than val (only if not found)\n }\n left = mid + 1;\n } else if (id[mid]! === val) {\n result = mid;\n found = true;\n // Continue searching to the left for leftmost occurrence\n right = mid - 1;\n } else {\n // id[mid] > val\n right = mid - 1;\n }\n }\n\n return result;\n}\n\n/**\n * Binary Search Rightmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the element to the right of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the right\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_rightmost(arr, 3);\n * // Returns: 3 (index of 5, which is right of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_rightmost(arr, 5);\n * // Returns: 3 (index of last instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns rightmost occurrence\n * - When value not found, returns position of next larger element\n */\nexport function binary_search_rightmost(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n let result = -1;\n let found = false;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! <= val) {\n if (id[mid]! === val) {\n result = mid;\n found = true;\n }\n // Continue searching to the right for rightmost occurrence\n left = mid + 1;\n } else {\n // id[mid] > val\n if (!found) {\n result = mid; // Track the first element greater than val (only if not found)\n }\n right = mid - 1;\n }\n }\n\n return result;\n}\n\n/**\n * Covariance\n *\n * Returns the covariance between two arrays.\n *\n * @param id1 - First array\n * @param id2 - Second array\n * @param biased - If true, uses biased estimate (population). If false, uses unbiased estimate (sample). Default: true\n * @returns Covariance between the two arrays\n *\n * @example\n * ```typescript\n * const prices = [100, 102, 98, 105, 103];\n * const volume = [1000, 1200, 950, 1300, 1100];\n * const cov = array.covariance(prices, volume);\n * // Returns covariance between price and volume\n * ```\n *\n * @remarks\n * - Biased (true): divides by n (population covariance)\n * - Unbiased (false): divides by n-1 (sample covariance)\n * - Returns NaN if arrays are empty or have different lengths\n * - Formula: Cov(X,Y) = E[(X - \u03BCX)(Y - \u03BCY)]\n */\nexport function covariance(id1: PineArray<float>, id2: PineArray<float>, biased: bool = true): float {\n if (id1.length === 0 || id2.length === 0) {\n return NaN;\n }\n\n if (id1.length !== id2.length) {\n return NaN;\n }\n\n const n = id1.length;\n const mean1 = avg(id1);\n const mean2 = avg(id2);\n\n let sum = 0;\n for (let i = 0; i < n; i++) {\n sum += (id1[i]! - mean1) * (id2[i]! - mean2);\n }\n\n // Biased: divide by n, Unbiased: divide by n-1\n const divisor = biased ? n : n - 1;\n return sum / divisor;\n}\n\n/**\n * Percentile Linear Interpolation\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using linear interpolation.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using linear interpolation\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_linear_interpolation(arr, 50);\n * // Returns: 3 (median)\n * ```\n *\n * @remarks\n * - Uses linear interpolation between adjacent values\n * - Result may not be a member of the array\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - position in the sorted array: `percentage / 100 * size - 0.5`, clamped to the first / last value, linear\n * interpolation between the two neighbours\n * - `na` values are sorted after all numbers; with an `na` in the array, a position between two values gives `na`\n */\nexport function percentile_linear_interpolation(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const s = sortedNaLast(id);\n const n = s.length;\n const pos = (percentage / 100) * n - 0.5;\n if (pos <= 0) return s[0]!;\n if (pos >= n - 1) return s[n - 1]!;\n const lo = Math.floor(pos);\n const f = pos - lo;\n if (f === 0) return s[lo]!;\n return Number.isNaN(s[n - 1]!) ? NaN : s[lo]! + f * (s[lo + 1]! - s[lo]!);\n}\n\n/** Array values sorted ascending, `na` values after the numbers (array.percentile_*). */\nfunction sortedNaLast(id: PineArray<float>): number[] {\n const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return [...numbers, ...Array<number>(id.length - numbers.length).fill(NaN)];\n}\n\n/**\n * Percentile Nearest Rank\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using the nearest-rank method.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using nearest rank\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_nearest_rank(arr, 50);\n * // Returns: 3 (median, always a member of array)\n * ```\n *\n * @remarks\n * - Result is always a member of the array\n * - Uses nearest-rank method (no interpolation)\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - the value at rank `ceil(percentage / 100 * size)` of the sorted array\n * - `na` values are sorted after all numbers (na when that rank holds an `na`)\n */\nexport function percentile_nearest_rank(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const s = sortedNaLast(id);\n const rank = Math.min(s.length, Math.max(1, Math.ceil((percentage / 100) * s.length)));\n return s[rank - 1]!;\n}\n\n/**\n * Percent Rank\n *\n * Returns the percentile rank of the element at the specified index.\n * The percentile rank is the percentage of elements that are less than\n * or equal to the reference value.\n *\n * @param id - Array of numeric values\n * @param index - Index of element to rank\n * @returns Percentile rank (0-100)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const rank = array.percentrank(arr, 2); // Value at index 2 is 3\n * // Returns: 40 (40% of values <= 3)\n * ```\n *\n * @remarks\n * - Returns percentage of elements <= the value at given index\n * - Range: 0 to 100\n * - Returns NaN if array is empty or index out of bounds\n */\nexport function percentrank(id: PineArray<float>, index: int): float {\n if (id.length === 0 || index < 0 || index >= id.length) {\n return NaN;\n }\n\n const value = id[index]!;\n\n if (isNaN(value)) {\n return NaN;\n }\n\n // Count elements less than or equal to the value\n let count = 0;\n for (let i = 0; i < id.length; i++) {\n if (!isNaN(id[i]!) && id[i]! <= value) {\n count++;\n }\n }\n\n // Calculate percentage\n return (count / id.length) * 100;\n}\n\n/**\n * Sort Indices\n *\n * Returns an array of indices which, when used to index the original array,\n * will access its elements in their sorted order. Does not modify the original array.\n *\n * @param id - Array to get sorted indices from\n * @param order - Sort order: 'asc' or 'desc' (default: 'asc')\n * @returns Array of indices in sorted order\n *\n * @example\n * ```typescript\n * const arr = [5, -2, 0, 9, 1];\n * const indices = array.sort_indices(arr); // [1, 2, 4, 0, 3]\n * // arr[1] = -2 (smallest)\n * // arr[2] = 0\n * // arr[4] = 1\n * // arr[0] = 5\n * // arr[3] = 9 (largest)\n * ```\n *\n * @remarks\n * - Original array is not modified\n * - Returns indices that would sort the array\n * - Useful for maintaining correspondence with other arrays\n */\nexport function sort_indices(id: PineArray<float>, order: 'asc' | 'desc' = 'asc'): PineArray<int> {\n // Create array of indices\n const indices: PineArray<int> = Array.from({ length: id.length }, (_, i) => i) as PineArray<int>;\n\n // Sort indices based on values in original array\n indices.sort((a, b) => {\n if (order === 'asc') {\n return id[a]! - id[b]!;\n } else {\n return id[b]! - id[a]!;\n }\n });\n\n return indices;\n}\n\n/**\n * Standardize\n *\n * Returns an array of standardized elements (z-score normalization).\n * Each element is transformed to (value - mean) / stddev.\n *\n * @param id - Array of numeric values\n * @returns Array of standardized values (z-scores)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const standardized = array.standardize(arr);\n * // Mean = 3, StdDev \u2248 1.414\n * // Result \u2248 [-1.414, -0.707, 0, 0.707, 1.414]\n * ```\n *\n * @remarks\n * - Formula: z = (x - \u03BC) / \u03C3\n * - Result has mean of 0 and standard deviation of 1\n * - Returns array of NaN if standard deviation is 0\n * - Useful for comparing values on different scales\n */\nexport function standardize(id: PineArray<float>): PineArray<float> {\n if (id.length === 0) {\n return [] as PineArray<float>;\n }\n\n const mean = avg(id);\n const stdDev = stdev(id);\n\n // If stddev is 0, all values are the same - return array of 0s or NaN\n if (stdDev === 0) {\n return id.map(() => NaN) as PineArray<float>;\n }\n\n // Calculate z-score for each element\n return id.map(value => (value - mean) / stdDev) as PineArray<float>;\n}\n\n/**\n * New Type (User-Defined Type Array)\n *\n * Creates a new array of user-defined type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements\n * @returns New array of user-defined type\n *\n * @example\n * ```typescript\n * // NOTE: User-defined types (UDTs) are not fully supported yet\n * // This is a placeholder for future implementation\n * const arr = array.newtype<MyType>(5);\n * ```\n *\n * @remarks\n * - **\u26A0\uFE0F LIMITED SUPPORT**: User-defined types (UDTs) require a type system\n * that is not yet fully implemented in this library\n * - This function currently works like `new_array<T>()` for basic types\n * - Full UDT support will be added in a future version\n * - See PineScript documentation for UDT usage patterns\n */\nexport function newtype<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n // For now, this is just an alias for new_array\n // Full UDT support requires implementing the type system\n return new_array<T>(size, initial_value);\n}\n\n/**\n * \u26A0\uFE0F RENDERING FUNCTIONS NOT IMPLEMENTED\n *\n * The following array constructor functions are intentionally excluded\n * because they create arrays for rendering objects, which are outside\n * the scope of this calculation-focused library:\n *\n * - `new_box()` - Creates arrays of box drawing objects\n * - `new_label()` - Creates arrays of label objects\n * - `new_line()` - Creates arrays of line drawing objects\n * - `new_linefill()` - Creates arrays of line fill objects\n * - `new_table()` - Creates arrays of table layout objects\n *\n * **Design Constraint**: This library focuses on calculation and indicator\n * functions only. Rendering, visualization, and UI functions require a\n * rendering engine and are not included.\n *\n * If you need these functions, consider:\n * 1. Using PineScript directly\n * 2. Implementing a rendering layer separately\n * 3. Using this library for calculations and another library for visualization\n */\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["size", "mode", "sum"]
|
|
7
7
|
}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - {@link whenCalled}: vectorized, when the bars of the calls are known in advance.
|
|
10
10
|
* - {@link crossover} / {@link crossunder} / {@link cross} / {@link barssince}: one stateful call site for bar
|
|
11
11
|
* loops, called only on the bars where the Pine call runs.
|
|
12
|
+
* - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each
|
|
13
|
+
* call), which PineScript computes with a state kept between calls.
|
|
12
14
|
*
|
|
13
15
|
* Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide
|
|
14
16
|
* the result. A ta.* call in the right operand of `a or b` runs on the bars where `a` is false, in `a and b` on the
|
|
@@ -58,4 +60,29 @@ export declare function crossunder(): (a: number, b: number) => boolean;
|
|
|
58
60
|
export declare function barssince(): (condition: boolean | number) => number;
|
|
59
61
|
/** One `ta.cross(a, b)` call site: false on its first call, as its history is na. */
|
|
60
62
|
export declare function cross(): (a: number, b: number) => boolean;
|
|
63
|
+
/**
|
|
64
|
+
* One `ta.lowest(source, length)` call site with a series length (a different length on each call), called with
|
|
65
|
+
* `(value, length)`.
|
|
66
|
+
*
|
|
67
|
+
* PineScript rules (measured with a length that changes on each bar):
|
|
68
|
+
* - the extreme is kept with its bar; a new value that passes it replaces it; when the kept extreme is `length`
|
|
69
|
+
* calls old, the last `length` values are scanned again (na skipped, the oldest wins a tie)
|
|
70
|
+
* - a length smaller than on the previous call: the last `length` values are scanned again
|
|
71
|
+
* - a length larger than on the previous call: the values that enter the window at its old end are compared with the
|
|
72
|
+
* extreme; when one of them is na, the extreme restarts from the current value (the values in between are not read)
|
|
73
|
+
* - an na value gives na and resets the extreme; na before call `length - 1`
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* // Pine: lowPrice = ta.lowest(close[1], lookback) // lookback changes per bar
|
|
78
|
+
* const lowPrice = callsite.lowest();
|
|
79
|
+
* const out = closes.map((_, i) => lowPrice(i > 0 ? closes[i - 1]! : NaN, lookback[i]!));
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function lowest(): (value: number, length: number) => number;
|
|
83
|
+
/**
|
|
84
|
+
* One `ta.highest(source, length)` call site with a series length (a different length on each call), called with
|
|
85
|
+
* `(value, length)`. Same rules as {@link lowest}.
|
|
86
|
+
*/
|
|
87
|
+
export declare function highest(): (value: number, length: number) => number;
|
|
61
88
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,EACnD,MAAM,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,EACnC,EAAE,EAAE,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAC3C,GAAG,OAAO,EAAE,MAAM,EAAE,GACnB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CASnB;AAcD,yFAAyF;AACzF,wBAAgB,SAAS,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE7D;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE9D;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,KAAK,MAAM,CAOnE;AAED,qFAAqF;AACrF,wBAAgB,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAEzD;AA2CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAElE;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAEnE"}
|
|
@@ -22,6 +22,8 @@ __export(callsite_exports, {
|
|
|
22
22
|
cross: () => cross,
|
|
23
23
|
crossover: () => crossover,
|
|
24
24
|
crossunder: () => crossunder,
|
|
25
|
+
highest: () => highest,
|
|
26
|
+
lowest: () => lowest,
|
|
25
27
|
whenCalled: () => whenCalled
|
|
26
28
|
});
|
|
27
29
|
module.exports = __toCommonJS(callsite_exports);
|
|
@@ -62,4 +64,49 @@ function barssince() {
|
|
|
62
64
|
function cross() {
|
|
63
65
|
return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb || a < b && pa >= pb);
|
|
64
66
|
}
|
|
67
|
+
function extremeSite(isLowest) {
|
|
68
|
+
const better = isLowest ? (a, b) => a < b : (a, b) => a > b;
|
|
69
|
+
const values = [];
|
|
70
|
+
let extreme = NaN;
|
|
71
|
+
let extremeAt = -1;
|
|
72
|
+
let prevLength = NaN;
|
|
73
|
+
const keep = (v, at) => {
|
|
74
|
+
extreme = v;
|
|
75
|
+
extremeAt = at;
|
|
76
|
+
};
|
|
77
|
+
const rescan = (i, length) => {
|
|
78
|
+
extreme = NaN;
|
|
79
|
+
for (let b = i; b > i - length && b >= 0; b--) {
|
|
80
|
+
const v = values[b];
|
|
81
|
+
if (!Number.isNaN(v) && (Number.isNaN(extreme) || !better(extreme, v))) keep(v, b);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
return (value, length) => {
|
|
85
|
+
const i = values.length;
|
|
86
|
+
values.push(value);
|
|
87
|
+
if (Number.isNaN(value)) {
|
|
88
|
+
extreme = NaN;
|
|
89
|
+
prevLength = length;
|
|
90
|
+
return NaN;
|
|
91
|
+
}
|
|
92
|
+
if (length > prevLength) {
|
|
93
|
+
const from = Math.max(0, i - length + 1);
|
|
94
|
+
const to = Math.max(0, i - prevLength + 1);
|
|
95
|
+
if (values.slice(from, to).some(Number.isNaN)) keep(value, i);
|
|
96
|
+
else {
|
|
97
|
+
for (let b = from; b < to; b++) if (Number.isNaN(extreme) || better(values[b], extreme)) keep(values[b], b);
|
|
98
|
+
if (Number.isNaN(extreme) || better(value, extreme)) keep(value, i);
|
|
99
|
+
}
|
|
100
|
+
} else if (length < prevLength || Number.isNaN(extreme) || i - extremeAt >= length) rescan(i, length);
|
|
101
|
+
else if (better(value, extreme)) keep(value, i);
|
|
102
|
+
prevLength = length;
|
|
103
|
+
return i < length - 1 ? NaN : extreme;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function lowest() {
|
|
107
|
+
return extremeSite(true);
|
|
108
|
+
}
|
|
109
|
+
function highest() {
|
|
110
|
+
return extremeSite(false);
|
|
111
|
+
}
|
|
65
112
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/callsite/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Per-call history of ta.* functions called in a conditional block.\n *\n * In PineScript, every ta.* call keeps its own history of the values it receives. A call inside\n * an `if` block receives values only on the bars where the block runs, so its history skips the\n * other bars: `ta.crossover(a, b)` is false on the first bar the block runs, and `ta.sma(x, 3)`\n * averages the last 3 values it received, not the last 3 bars.\n *\n * - {@link whenCalled}: vectorized, when the bars of the calls are known in advance.\n * - {@link crossover} / {@link crossunder} / {@link cross} / {@link barssince}: one stateful call site for bar\n * loops, called only on the bars where the Pine call runs.\n *\n * Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide\n * the result. A ta.* call in the right operand of `a or b` runs on the bars where `a` is false, in `a and b` on the\n * bars where `a` is true, so it needs a call site too:\n *\n * ```typescript\n * // Pine: longCond = longUp or (src > sig and ta.barssince(longUp) <= lookback)\n * const since = callsite.whenCalled(longUp.map((u, i) => !u && src[i] > sig[i]), (c) => taCore.barssince(c.map(Boolean)), longUp);\n * // ta.barssince(longUp) only runs where longUp is false: it never sees true and stays na\n * ```\n *\n * ```typescript\n * // Pine: if inRange\n * // buy = ta.crossover(cumRsi, 60)\n * const buy = callsite.whenCalled(inRange, (a) => taCore.crossover(a, a.map(() => 60)), cumRsi);\n *\n * // Same call in a bar loop\n * const buyCross = callsite.crossover();\n * for (let i = 0; i < n; i++) {\n * if (inRange[i]) {\n * const buy = buyCross(cumRsi[i], 60);\n * }\n * }\n * ```\n *\n * @module callsite\n */\n\nimport type { Source } from '../types/index.js';\n\n/**\n * Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.\n * `fn` receives the values of `sources` on those bars, in order; its results are placed back on\n * the same bars. The other bars get na (NaN).\n *\n * @param called - true (or non-zero) on the bars where the call runs\n * @param fn - the calculation, for example `(x) => taCore.sma(x, 3)`\n * @param sources - the arguments of the call, one value per chart bar\n */\nexport function whenCalled<T extends number | boolean>(\n called: ArrayLike<boolean | number>,\n fn: (...values: number[][]) => ArrayLike<T>,\n ...sources: Source[]\n): Array<T | number> {\n const bars: number[] = [];\n for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);\n const result = fn(...sources.map(s => bars.map(i => s[i] ?? NaN)));\n const out = new Array<T | number>(called.length).fill(NaN);\n bars.forEach((bar, k) => {\n out[bar] = result[k]!;\n });\n return out;\n}\n\n/** A call site that keeps the two previous arguments (na before the first call). */\nfunction twoSeriesSite(test: (a: number, b: number, prevA: number, prevB: number) => boolean) {\n let prevA = NaN;\n let prevB = NaN;\n return (a: number, b: number): boolean => {\n const result = test(a, b, prevA, prevB);\n prevA = a;\n prevB = b;\n return result;\n };\n}\n\n/** One `ta.crossover(a, b)` call site: false on its first call, as its history is na. */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/** One `ta.crossunder(a, b)` call site: false on its first call, as its history is na. */\nexport function crossunder(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a < b && pa >= pb);\n}\n\n/**\n * One `ta.barssince(condition)` call site: the number of calls since the condition was true on a call (0 on that\n * call), na before the first true condition. An na condition counts as false.\n */\nexport function barssince(): (condition: boolean | number) => number {\n let count = NaN;\n return (condition) => {\n if (condition && !Number.isNaN(condition)) count = 0;\n else if (!Number.isNaN(count)) count++;\n return count;\n };\n}\n\n/** One `ta.cross(a, b)` call site: false on its first call, as its history is na. */\nexport function cross(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => (a > b && pa <= pb) || (a < b && pa >= pb));\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Per-call history of ta.* functions called in a conditional block.\n *\n * In PineScript, every ta.* call keeps its own history of the values it receives. A call inside\n * an `if` block receives values only on the bars where the block runs, so its history skips the\n * other bars: `ta.crossover(a, b)` is false on the first bar the block runs, and `ta.sma(x, 3)`\n * averages the last 3 values it received, not the last 3 bars.\n *\n * - {@link whenCalled}: vectorized, when the bars of the calls are known in advance.\n * - {@link crossover} / {@link crossunder} / {@link cross} / {@link barssince}: one stateful call site for bar\n * loops, called only on the bars where the Pine call runs.\n * - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each\n * call), which PineScript computes with a state kept between calls.\n *\n * Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide\n * the result. A ta.* call in the right operand of `a or b` runs on the bars where `a` is false, in `a and b` on the\n * bars where `a` is true, so it needs a call site too:\n *\n * ```typescript\n * // Pine: longCond = longUp or (src > sig and ta.barssince(longUp) <= lookback)\n * const since = callsite.whenCalled(longUp.map((u, i) => !u && src[i] > sig[i]), (c) => taCore.barssince(c.map(Boolean)), longUp);\n * // ta.barssince(longUp) only runs where longUp is false: it never sees true and stays na\n * ```\n *\n * ```typescript\n * // Pine: if inRange\n * // buy = ta.crossover(cumRsi, 60)\n * const buy = callsite.whenCalled(inRange, (a) => taCore.crossover(a, a.map(() => 60)), cumRsi);\n *\n * // Same call in a bar loop\n * const buyCross = callsite.crossover();\n * for (let i = 0; i < n; i++) {\n * if (inRange[i]) {\n * const buy = buyCross(cumRsi[i], 60);\n * }\n * }\n * ```\n *\n * @module callsite\n */\n\nimport type { Source } from '../types/index.js';\n\n/**\n * Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.\n * `fn` receives the values of `sources` on those bars, in order; its results are placed back on\n * the same bars. The other bars get na (NaN).\n *\n * @param called - true (or non-zero) on the bars where the call runs\n * @param fn - the calculation, for example `(x) => taCore.sma(x, 3)`\n * @param sources - the arguments of the call, one value per chart bar\n */\nexport function whenCalled<T extends number | boolean>(\n called: ArrayLike<boolean | number>,\n fn: (...values: number[][]) => ArrayLike<T>,\n ...sources: Source[]\n): Array<T | number> {\n const bars: number[] = [];\n for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);\n const result = fn(...sources.map(s => bars.map(i => s[i] ?? NaN)));\n const out = new Array<T | number>(called.length).fill(NaN);\n bars.forEach((bar, k) => {\n out[bar] = result[k]!;\n });\n return out;\n}\n\n/** A call site that keeps the two previous arguments (na before the first call). */\nfunction twoSeriesSite(test: (a: number, b: number, prevA: number, prevB: number) => boolean) {\n let prevA = NaN;\n let prevB = NaN;\n return (a: number, b: number): boolean => {\n const result = test(a, b, prevA, prevB);\n prevA = a;\n prevB = b;\n return result;\n };\n}\n\n/** One `ta.crossover(a, b)` call site: false on its first call, as its history is na. */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/** One `ta.crossunder(a, b)` call site: false on its first call, as its history is na. */\nexport function crossunder(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a < b && pa >= pb);\n}\n\n/**\n * One `ta.barssince(condition)` call site: the number of calls since the condition was true on a call (0 on that\n * call), na before the first true condition. An na condition counts as false.\n */\nexport function barssince(): (condition: boolean | number) => number {\n let count = NaN;\n return (condition) => {\n if (condition && !Number.isNaN(condition)) count = 0;\n else if (!Number.isNaN(count)) count++;\n return count;\n };\n}\n\n/** One `ta.cross(a, b)` call site: false on its first call, as its history is na. */\nexport function cross(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => (a > b && pa <= pb) || (a < b && pa >= pb));\n}\n\n/** One `ta.lowest` / `ta.highest` call site with a series length; rules in {@link lowest}. */\nfunction extremeSite(isLowest: boolean): (value: number, length: number) => number {\n const better = isLowest ? (a: number, b: number) => a < b : (a: number, b: number) => a > b;\n const values: number[] = [];\n let extreme = NaN;\n let extremeAt = -1;\n let prevLength = NaN;\n const keep = (v: number, at: number) => {\n extreme = v;\n extremeAt = at;\n };\n const rescan = (i: number, length: number) => {\n extreme = NaN;\n for (let b = i; b > i - length && b >= 0; b--) {\n const v = values[b]!;\n if (!Number.isNaN(v) && (Number.isNaN(extreme) || !better(extreme, v))) keep(v, b);\n }\n };\n return (value, length) => {\n const i = values.length;\n values.push(value);\n if (Number.isNaN(value)) {\n extreme = NaN;\n prevLength = length;\n return NaN;\n }\n if (length > prevLength) {\n const from = Math.max(0, i - length + 1);\n const to = Math.max(0, i - prevLength + 1);\n if (values.slice(from, to).some(Number.isNaN)) keep(value, i);\n else {\n for (let b = from; b < to; b++) if (Number.isNaN(extreme) || better(values[b]!, extreme)) keep(values[b]!, b);\n if (Number.isNaN(extreme) || better(value, extreme)) keep(value, i);\n }\n } else if (length < prevLength || Number.isNaN(extreme) || i - extremeAt >= length) rescan(i, length);\n else if (better(value, extreme)) keep(value, i);\n prevLength = length;\n return i < length - 1 ? NaN : extreme;\n };\n}\n\n/**\n * One `ta.lowest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`.\n *\n * PineScript rules (measured with a length that changes on each bar):\n * - the extreme is kept with its bar; a new value that passes it replaces it; when the kept extreme is `length`\n * calls old, the last `length` values are scanned again (na skipped, the oldest wins a tie)\n * - a length smaller than on the previous call: the last `length` values are scanned again\n * - a length larger than on the previous call: the values that enter the window at its old end are compared with the\n * extreme; when one of them is na, the extreme restarts from the current value (the values in between are not read)\n * - an na value gives na and resets the extreme; na before call `length - 1`\n *\n * @example\n * ```typescript\n * // Pine: lowPrice = ta.lowest(close[1], lookback) // lookback changes per bar\n * const lowPrice = callsite.lowest();\n * const out = closes.map((_, i) => lowPrice(i > 0 ? closes[i - 1]! : NaN, lookback[i]!));\n * ```\n */\nexport function lowest(): (value: number, length: number) => number {\n return extremeSite(true);\n}\n\n/**\n * One `ta.highest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`. Same rules as {@link lowest}.\n */\nexport function highest(): (value: number, length: number) => number {\n return extremeSite(false);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -243,6 +243,7 @@ export declare const yellow = "#FDD835";
|
|
|
243
243
|
* @remarks
|
|
244
244
|
* PineScript rules:
|
|
245
245
|
* - If value <= bottom_value, returns bottom_color; else if value >= top_value, returns top_color
|
|
246
|
+
* - An inverted range (bottom_value > top_value) returns bottom_color, wherever the value is
|
|
246
247
|
* - Otherwise the colours are mixed with their transparency (premultiplied alpha, alpha as a byte); the RGB channels
|
|
247
248
|
* and the alpha are truncated. PineScript's float rounding order is not known: a channel can differ by 1 when the
|
|
248
249
|
* exact result is an integer (same RGB at both ends)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/color/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/color/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAcrF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAUvG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CASnE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAIxE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,GAAG,CAEjC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,GAAG,CAEjC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,GAAG,CAEjC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAEnC;AAID;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,MAAM,YAAY,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,MAAM,YAAY,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,MAAM,YAAY,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,GAAG,YAAY,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,MAAM,YAAY,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,IAAI,YAAY,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,MAAM,YAAY,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,KAAK,EACnB,SAAS,EAAE,KAAK,EAChB,YAAY,EAAE,KAAK,EACnB,SAAS,EAAE,KAAK,GACf,MAAM,CA0BR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,IAAI,GAAG,EAAE,CAAC"}
|
package/dist/cjs/color/index.js
CHANGED
|
@@ -46,6 +46,7 @@ __export(color_exports, {
|
|
|
46
46
|
yellow: () => yellow
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(color_exports);
|
|
49
|
+
var import_parse = require("./parse.js");
|
|
49
50
|
const channel = (v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));
|
|
50
51
|
const alphaOf = (transp) => transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;
|
|
51
52
|
function rgb(red2, green2, blue2, transp) {
|
|
@@ -66,42 +67,20 @@ function from_hex(hex, transp) {
|
|
|
66
67
|
return rgb(r2, g2, b2, transp);
|
|
67
68
|
}
|
|
68
69
|
function new_color(baseColor, transp) {
|
|
69
|
-
const rgba = parseColor(baseColor);
|
|
70
|
+
const rgba = (0, import_parse.parseColor)(baseColor);
|
|
70
71
|
return rgb(rgba.r, rgba.g, rgba.b, transp);
|
|
71
72
|
}
|
|
72
73
|
function r(clr) {
|
|
73
|
-
return parseColor(clr).r;
|
|
74
|
+
return (0, import_parse.parseColor)(clr).r;
|
|
74
75
|
}
|
|
75
76
|
function g(clr) {
|
|
76
|
-
return parseColor(clr).g;
|
|
77
|
+
return (0, import_parse.parseColor)(clr).g;
|
|
77
78
|
}
|
|
78
79
|
function b(clr) {
|
|
79
|
-
return parseColor(clr).b;
|
|
80
|
+
return (0, import_parse.parseColor)(clr).b;
|
|
80
81
|
}
|
|
81
82
|
function t(clr) {
|
|
82
|
-
|
|
83
|
-
return Math.round((1 - alpha / 255) * 100);
|
|
84
|
-
}
|
|
85
|
-
function parseColor(clr) {
|
|
86
|
-
if (typeof clr === "string") {
|
|
87
|
-
const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(clr.trim());
|
|
88
|
-
if (hex) {
|
|
89
|
-
let digits = hex[1];
|
|
90
|
-
if (digits.length <= 4) digits = [...digits].map((c) => c + c).join("");
|
|
91
|
-
const byte = (k) => parseInt(digits.slice(k, k + 2), 16);
|
|
92
|
-
return { r: byte(0), g: byte(2), b: byte(4), t: digits.length === 8 ? (1 - byte(6) / 255) * 100 : 0 };
|
|
93
|
-
}
|
|
94
|
-
const match = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
95
|
-
if (match) {
|
|
96
|
-
return {
|
|
97
|
-
r: parseInt(match[1]),
|
|
98
|
-
g: parseInt(match[2]),
|
|
99
|
-
b: parseInt(match[3]),
|
|
100
|
-
t: match[4] ? (1 - parseFloat(match[4])) * 100 : 0
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return { r: 0, g: 0, b: 0, t: 0 };
|
|
83
|
+
return Math.round((1 - (0, import_parse.alphaByte)((0, import_parse.parseColor)(clr).a) / 255) * 100);
|
|
105
84
|
}
|
|
106
85
|
const aqua = "#00BCD4";
|
|
107
86
|
const black = "#363A45";
|
|
@@ -125,11 +104,11 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
|
|
|
125
104
|
if ([value, bottom_value, top_value].some((v) => v === null || v === void 0 || Number.isNaN(v)) || bottom_value === top_value) {
|
|
126
105
|
return transparent;
|
|
127
106
|
}
|
|
128
|
-
const k = value <= bottom_value ? 0 : value >= top_value ? 1 : (value - bottom_value) / (top_value - bottom_value);
|
|
107
|
+
const k = value <= bottom_value || bottom_value > top_value ? 0 : value >= top_value ? 1 : (value - bottom_value) / (top_value - bottom_value);
|
|
129
108
|
const rgba = (c) => {
|
|
130
109
|
if (c === null || c === void 0) return { r: 0, g: 0, b: 0, a: 0 };
|
|
131
|
-
const p = parseColor(c);
|
|
132
|
-
return { r: p.r, g: p.g, b: p.b, a:
|
|
110
|
+
const p = (0, import_parse.parseColor)(c);
|
|
111
|
+
return { r: p.r, g: p.g, b: p.b, a: (0, import_parse.alphaByte)(p.a) };
|
|
133
112
|
};
|
|
134
113
|
const c1 = rgba(bottom_color);
|
|
135
114
|
const c2 = rgba(top_color);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/color/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Color namespace\n * Mirrors PineScript's color.* functions for color creation and manipulation.\n *\n * @remarks\n * All color functions in this namespace follow PineScript v6 API specifications.\n * Colors are represented as RGB or RGBA strings.\n * Transparency values range from 0 (fully opaque) to 100 (fully transparent).\n *\n * @version 6\n */\n\nimport type { color, int, float, simple_int, simple_float } from '../types/index.js';\n\n/** Channel of color.rgb: na is 0, a fraction is truncated. */\nconst channel = (v: number): int =>\n v === null || v === undefined || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));\n\n/** Alpha (0-1) of a transparency given to color.rgb / color.new: na is fully transparent, clamped to 0..100. */\nconst alphaOf = (transp: number): float =>\n transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;\n\n/**\n * Creates a color from RGB values with optional transparency.\n *\n * @param red - Red component (0-255, values are clamped)\n * @param green - Green component (0-255, values are clamped)\n * @param blue - Blue component (0-255, values are clamped)\n * @param transp - Optional transparency (0-100). 0 = opaque, 100 = fully transparent\n * @returns Color string in rgb() or rgba() format\n *\n * @remarks\n * - RGB values are automatically clamped to the 0-255 range\n * - Transparency of 0 or omitted results in rgb() format\n * - Transparency > 0 results in rgba() format\n * - Transparency is converted to alpha channel (0-1 range)\n *\n * PineScript rules:\n * - an `na` channel is 0; a fractional channel is truncated (127.6 is 127)\n * - the transparency is clamped to 0..100 (140 is fully transparent, -5 is opaque); an `na` transparency is fully\n * transparent\n *\n * @example\n * ```typescript\n * color.rgb(255, 0, 0) // Returns: \"rgb(255, 0, 0)\" - Red\n * color.rgb(0, 255, 0, 50) // Returns: \"rgba(0, 255, 0, 0.5)\" - Semi-transparent green\n * color.rgb(300, 0, 0) // Returns: \"rgb(255, 0, 0)\" - Clamped to 255\n * ```\n */\nexport function rgb(red: simple_int, green: simple_int, blue: simple_int, transp?: simple_float): string {\n const r = channel(red);\n const g = channel(green);\n const b = channel(blue);\n const a = transp !== undefined ? alphaOf(transp) : 1;\n\n if (a === 1) {\n return `rgb(${r}, ${g}, ${b})`;\n }\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\n/**\n * Creates a color from a hexadecimal string with optional transparency.\n *\n * @param hex - Hex color string (with or without '#' prefix, e.g., \"#FF0000\" or \"FF0000\")\n * @param transp - Optional transparency (0-100). 0 = opaque, 100 = fully transparent\n * @returns Color string in rgb() or rgba() format\n *\n * @remarks\n * - Accepts hex strings with or without '#' prefix\n * - Case-insensitive (accepts both \"FF0000\" and \"ff0000\")\n * - Must be 6 characters (excluding '#')\n * - Format: RRGGBB where each component is 00-FF\n *\n * @example\n * ```typescript\n * color.from_hex(\"#FF0000\") // Returns: \"rgb(255, 0, 0)\" - Red\n * color.from_hex(\"00FF00\", 50) // Returns: \"rgba(0, 255, 0, 0.5)\" - Semi-transparent green\n * color.from_hex(\"#0000FF\") // Returns: \"rgb(0, 0, 255)\" - Blue\n * color.from_hex(\"FFA500\") // Returns: \"rgb(255, 165, 0)\" - Orange\n * ```\n */\nexport function from_hex(hex: string, transp?: simple_float): string {\n // Remove # if present\n hex = hex.replace('#', '');\n\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n return rgb(r, g, b, transp);\n}\n\n/**\n * Creates a new color with modified transparency, preserving RGB components.\n *\n * @param baseColor - The base color to modify\n * @param transp - New transparency value (0-100). 0 = opaque, 100 = fully transparent\n * @returns New color with updated transparency\n *\n * @remarks\n * - Preserves the RGB values from the base color\n * - Replaces the transparency with the new value\n * - Useful for creating semi-transparent versions of existing colors\n * - PineScript clamps the transparency to 0..100 (`color.new(c, 140)` is fully transparent, `color.new(c, -5)` is\n * opaque); an `na` transparency is fully transparent\n *\n * @example\n * ```typescript\n * const red = color.rgb(255, 0, 0)\n * color.new_color(red, 50) // Returns: \"rgba(255, 0, 0, 0.5)\" - Semi-transparent red\n * color.new_color(red, 0) // Returns: \"rgb(255, 0, 0)\" - Fully opaque\n * color.new_color(red, 100) // Returns: \"rgba(255, 0, 0, 0)\" - Fully transparent\n * ```\n */\nexport function new_color(baseColor: color, transp: simple_float): string {\n // Parse the color and apply transparency\n const rgba = parseColor(baseColor);\n return rgb(rgba.r, rgba.g, rgba.b, transp);\n}\n\n/**\n * Extracts the red component from a color.\n *\n * @param clr - The color to extract from\n * @returns Red component value (0-255)\n *\n * @example\n * ```typescript\n * color.r(color.rgb(255, 128, 64)) // Returns: 255\n * color.r(color.from_hex(\"#FF0000\")) // Returns: 255\n * color.r(color.from_hex(\"#FFA500\")) // Returns: 255 (orange)\n * ```\n */\nexport function r(clr: color): int {\n return parseColor(clr).r;\n}\n\n/**\n * Extracts the green component from a color.\n *\n * @param clr - The color to extract from\n * @returns Green component value (0-255)\n *\n * @example\n * ```typescript\n * color.g(color.rgb(255, 128, 64)) // Returns: 128\n * color.g(color.from_hex(\"#00FF00\")) // Returns: 255\n * color.g(color.from_hex(\"#FFA500\")) // Returns: 165 (orange)\n * ```\n */\nexport function g(clr: color): int {\n return parseColor(clr).g;\n}\n\n/**\n * Extracts the blue component from a color.\n *\n * @param clr - The color to extract from\n * @returns Blue component value (0-255)\n *\n * @example\n * ```typescript\n * color.b(color.rgb(255, 128, 64)) // Returns: 64\n * color.b(color.from_hex(\"#0000FF\")) // Returns: 255\n * color.b(color.from_hex(\"#FFA500\")) // Returns: 0 (orange)\n * ```\n */\nexport function b(clr: color): int {\n return parseColor(clr).b;\n}\n\n/**\n * Extracts the transparency component from a color.\n *\n * @param clr - The color to extract from\n * @returns Transparency value (0-100). 0 = fully opaque, 100 = fully transparent\n *\n * @remarks\n * - Returns 0 for colors without transparency (rgb format)\n * - Converts alpha channel (0-1) to transparency (0-100)\n * - PineScript stores the alpha as a byte (0-255) and returns an integer transparency:\n * `color.t(color.new(c, 33.3))` is 33\n *\n * @example\n * ```typescript\n * color.t(color.rgb(255, 0, 0)) // Returns: 0 (opaque)\n * color.t(color.rgb(255, 0, 0, 50)) // Returns: 50\n * color.t(color.rgb(255, 0, 0, 100)) // Returns: 100 (fully transparent)\n * ```\n */\nexport function t(clr: color): float {\n const alpha = Math.round((1 - parseColor(clr).t / 100) * 255);\n return Math.round((1 - alpha / 255) * 100);\n}\n\n/**\n * Helper function to parse color string to RGBA components.\n *\n * @internal\n * @param clr - The color string to parse\n * @returns Object containing r, g, b (0-255) and t (0-100) components\n */\nfunction parseColor(clr: color): { r: int; g: int; b: int; t: float } {\n if (typeof clr === 'string') {\n // Hex: #RRGGBB, #RRGGBBAA (PineScript literals), #RGB, #RGBA\n const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(clr.trim());\n if (hex) {\n let digits = hex[1]!;\n if (digits.length <= 4) digits = [...digits].map((c) => c + c).join('');\n const byte = (k: number) => parseInt(digits.slice(k, k + 2), 16);\n return { r: byte(0), g: byte(2), b: byte(4), t: digits.length === 8 ? (1 - byte(6) / 255) * 100 : 0 };\n }\n // Handle rgb() or rgba() format\n const match = clr.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/);\n if (match) {\n return {\n r: parseInt(match[1]!),\n g: parseInt(match[2]!),\n b: parseInt(match[3]!),\n t: match[4] ? (1 - parseFloat(match[4])) * 100 : 0,\n };\n }\n }\n return { r: 0, g: 0, b: 0, t: 0 };\n}\n\n// Predefined color constants of PineScript v6.\n// PineScript v5 differs for red (#FF5252), teal (#00897B) and yellow (#FFEB3B).\n/**\n * Aqua/Cyan color constant\n * @constant {string} #00BCD4 - RGB(0, 188, 212)\n */\nexport const aqua = '#00BCD4';\n\n/**\n * Black color constant\n * @constant {string} #363A45 - RGB(54, 58, 69)\n */\nexport const black = '#363A45';\n\n/**\n * Blue color constant\n * @constant {string} #2962FF - RGB(41, 98, 255)\n */\nexport const blue = '#2962FF';\n\n/**\n * Fuchsia/Magenta color constant\n * @constant {string} #E040FB - RGB(224, 64, 251)\n */\nexport const fuchsia = '#E040FB';\n\n/**\n * Gray color constant\n * @constant {string} #787B86 - RGB(120, 123, 134)\n */\nexport const gray = '#787B86';\n\n/**\n * Green color constant (same as lime)\n * @constant {string} #4CAF50 - RGB(76, 175, 80)\n */\nexport const green = '#4CAF50';\n\n/**\n * Lime color constant (same as green)\n * @constant {string} #00E676 - RGB(0, 230, 118)\n */\nexport const lime = '#00E676';\n\n/**\n * Maroon color constant\n * @constant {string} #880E4F - RGB(136, 14, 79)\n */\nexport const maroon = '#880E4F';\n\n/**\n * Navy color constant\n * @constant {string} #311B92 - RGB(49, 27, 146)\n */\nexport const navy = '#311B92';\n\n/**\n * Olive color constant\n * @constant {string} #808000 - RGB(128, 128, 0)\n */\nexport const olive = '#808000';\n\n/**\n * Orange color constant\n * @constant {string} #FF9800 - RGB(255, 152, 0)\n */\nexport const orange = '#FF9800';\n\n/**\n * Purple color constant\n * @constant {string} #9C27B0 - RGB(156, 39, 176)\n */\nexport const purple = '#9C27B0';\n\n/**\n * Red color constant\n * @constant {string} #F23645 - RGB(242, 54, 69)\n */\nexport const red = '#F23645';\n\n/**\n * Silver color constant\n * @constant {string} #B2B5BE - RGB(178, 181, 190)\n */\nexport const silver = '#B2B5BE';\n\n/**\n * Teal color constant\n * @constant {string} #089981 - RGB(8, 153, 129)\n */\nexport const teal = '#089981';\n\n/**\n * White color constant\n * @constant {string} #FFFFFF - RGB(255, 255, 255)\n */\nexport const white = '#FFFFFF';\n\n/**\n * Yellow color constant\n * @constant {string} #FDD835 - RGB(253, 216, 53)\n */\nexport const yellow = '#FDD835';\n\n/**\n * Creates a color from a gradient based on value position.\n *\n * @param value - Value to calculate position-dependent color\n * @param bottom_value - Bottom position value corresponding to bottom_color\n * @param top_value - Top position value corresponding to top_color\n * @param bottom_color - Bottom position color\n * @param top_color - Top position color\n * @returns Color calculated from linear gradient\n *\n * @remarks\n * PineScript rules:\n * - If value <= bottom_value, returns bottom_color; else if value >= top_value, returns top_color\n * - Otherwise the colours are mixed with their transparency (premultiplied alpha, alpha as a byte); the RGB channels\n * and the alpha are truncated. PineScript's float rounding order is not known: a channel can differ by 1 when the\n * exact result is an integer (same RGB at both ends)\n * - An na value or bottom_value / top_value, or bottom_value == top_value, gives a fully transparent colour\n * - An na colour counts as fully transparent\n * - Works with rgb(), rgba() and hex (#RRGGBB, #RRGGBBAA) colours\n *\n * @example\n * ```typescript\n * // Value at middle of range gets middle color\n * const midColor = color.from_gradient(50, 0, 100,\n * color.rgb(255, 0, 0), // Red at bottom\n * color.rgb(0, 255, 0) // Green at top\n * ); // Returns color between red and green\n *\n * // Value at extremes\n * const lowColor = color.from_gradient(-10, 0, 100, red, green); // Returns red\n * const highColor = color.from_gradient(150, 0, 100, red, green); // Returns green\n * ```\n */\nexport function from_gradient(\n value: float,\n bottom_value: float,\n top_value: float,\n bottom_color: color,\n top_color: color\n): string {\n const transparent = 'rgba(0, 0, 0, 0)';\n if ([value, bottom_value, top_value].some((v) => v === null || v === undefined || Number.isNaN(v)) || bottom_value === top_value) {\n return transparent;\n }\n const k = value <= bottom_value ? 0 : value >= top_value ? 1 : (value - bottom_value) / (top_value - bottom_value);\n // alpha as a byte (0-255), as PineScript stores it; an na colour (null / undefined) is fully transparent\n const rgba = (c: color) => {\n if (c === null || c === undefined) return { r: 0, g: 0, b: 0, a: 0 };\n const p = parseColor(c);\n return { r: p.r, g: p.g, b: p.b, a: Math.round((1 - p.t / 100) * 255) };\n };\n const c1 = rgba(bottom_color);\n const c2 = rgba(top_color);\n const a = c1.a * (1 - k) + c2.a * k;\n if (a === 0) return transparent;\n // operation order with the fewest differences to PineScript (channels as 0-1, alpha as a byte)\n const mix = (x1: number, x2: number) => Math.floor((((x1 / 255) * c1.a) * (1 - k) + ((x2 / 255) * c2.a) * k) / (a / 255));\n const [r, g, b] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];\n const alpha = Math.floor(a);\n return alpha === 255 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${alpha / 255})`;\n}\n\n/**\n * Alias for new_color function.\n * Creates a new color with specified transparency from an existing color.\n *\n * @param baseColor - The base color\n * @param transp - Transparency value (0-100). 0 = fully opaque, 100 = fully transparent\n * @returns New color with applied transparency\n *\n * @remarks\n * This is an alias for `new_color()` to match PineScript's `color.new()` syntax.\n *\n * @example\n * ```typescript\n * const redColor = color.rgb(255, 0, 0);\n * const transparentRed = color.new(redColor, 50); // 50% transparent red\n * ```\n */\nexport { new_color as new };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * Color namespace\n * Mirrors PineScript's color.* functions for color creation and manipulation.\n *\n * @remarks\n * All color functions in this namespace follow PineScript v6 API specifications.\n * Colors are represented as RGB or RGBA strings.\n * Transparency values range from 0 (fully opaque) to 100 (fully transparent).\n *\n * @version 6\n */\n\nimport type { color, int, float, simple_int, simple_float } from '../types/index.js';\nimport { alphaByte, parseColor } from './parse.js';\n\n/** Channel of color.rgb: na is 0, a fraction is truncated. */\nconst channel = (v: number): int =>\n v === null || v === undefined || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));\n\n/**\n * Alpha (0-1) of a transparency given to color.rgb / color.new: na is fully transparent, clamped to 0..100.\n * `1 - t / 100` as in PineScript: `color.new(c, 90)` has the alpha byte 25 (0.09999999999999998 * 255 rounded).\n */\nconst alphaOf = (transp: number): float =>\n transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;\n\n/**\n * Creates a color from RGB values with optional transparency.\n *\n * @param red - Red component (0-255, values are clamped)\n * @param green - Green component (0-255, values are clamped)\n * @param blue - Blue component (0-255, values are clamped)\n * @param transp - Optional transparency (0-100). 0 = opaque, 100 = fully transparent\n * @returns Color string in rgb() or rgba() format\n *\n * @remarks\n * - RGB values are automatically clamped to the 0-255 range\n * - Transparency of 0 or omitted results in rgb() format\n * - Transparency > 0 results in rgba() format\n * - Transparency is converted to alpha channel (0-1 range)\n *\n * PineScript rules:\n * - an `na` channel is 0; a fractional channel is truncated (127.6 is 127)\n * - the transparency is clamped to 0..100 (140 is fully transparent, -5 is opaque); an `na` transparency is fully\n * transparent\n *\n * @example\n * ```typescript\n * color.rgb(255, 0, 0) // Returns: \"rgb(255, 0, 0)\" - Red\n * color.rgb(0, 255, 0, 50) // Returns: \"rgba(0, 255, 0, 0.5)\" - Semi-transparent green\n * color.rgb(300, 0, 0) // Returns: \"rgb(255, 0, 0)\" - Clamped to 255\n * ```\n */\nexport function rgb(red: simple_int, green: simple_int, blue: simple_int, transp?: simple_float): string {\n const r = channel(red);\n const g = channel(green);\n const b = channel(blue);\n const a = transp !== undefined ? alphaOf(transp) : 1;\n\n if (a === 1) {\n return `rgb(${r}, ${g}, ${b})`;\n }\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\n/**\n * Creates a color from a hexadecimal string with optional transparency.\n *\n * @param hex - Hex color string (with or without '#' prefix, e.g., \"#FF0000\" or \"FF0000\")\n * @param transp - Optional transparency (0-100). 0 = opaque, 100 = fully transparent\n * @returns Color string in rgb() or rgba() format\n *\n * @remarks\n * - Accepts hex strings with or without '#' prefix\n * - Case-insensitive (accepts both \"FF0000\" and \"ff0000\")\n * - Must be 6 characters (excluding '#')\n * - Format: RRGGBB where each component is 00-FF\n *\n * @example\n * ```typescript\n * color.from_hex(\"#FF0000\") // Returns: \"rgb(255, 0, 0)\" - Red\n * color.from_hex(\"00FF00\", 50) // Returns: \"rgba(0, 255, 0, 0.5)\" - Semi-transparent green\n * color.from_hex(\"#0000FF\") // Returns: \"rgb(0, 0, 255)\" - Blue\n * color.from_hex(\"FFA500\") // Returns: \"rgb(255, 165, 0)\" - Orange\n * ```\n */\nexport function from_hex(hex: string, transp?: simple_float): string {\n // Remove # if present\n hex = hex.replace('#', '');\n\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n return rgb(r, g, b, transp);\n}\n\n/**\n * Creates a new color with modified transparency, preserving RGB components.\n *\n * @param baseColor - The base color to modify\n * @param transp - New transparency value (0-100). 0 = opaque, 100 = fully transparent\n * @returns New color with updated transparency\n *\n * @remarks\n * - Preserves the RGB values from the base color\n * - Replaces the transparency with the new value\n * - Useful for creating semi-transparent versions of existing colors\n * - PineScript clamps the transparency to 0..100 (`color.new(c, 140)` is fully transparent, `color.new(c, -5)` is\n * opaque); an `na` transparency is fully transparent\n *\n * @example\n * ```typescript\n * const red = color.rgb(255, 0, 0)\n * color.new_color(red, 50) // Returns: \"rgba(255, 0, 0, 0.5)\" - Semi-transparent red\n * color.new_color(red, 0) // Returns: \"rgb(255, 0, 0)\" - Fully opaque\n * color.new_color(red, 100) // Returns: \"rgba(255, 0, 0, 0)\" - Fully transparent\n * ```\n */\nexport function new_color(baseColor: color, transp: simple_float): string {\n // Parse the color and apply transparency\n const rgba = parseColor(baseColor);\n return rgb(rgba.r, rgba.g, rgba.b, transp);\n}\n\n/**\n * Extracts the red component from a color.\n *\n * @param clr - The color to extract from\n * @returns Red component value (0-255)\n *\n * @example\n * ```typescript\n * color.r(color.rgb(255, 128, 64)) // Returns: 255\n * color.r(color.from_hex(\"#FF0000\")) // Returns: 255\n * color.r(color.from_hex(\"#FFA500\")) // Returns: 255 (orange)\n * ```\n */\nexport function r(clr: color): int {\n return parseColor(clr).r;\n}\n\n/**\n * Extracts the green component from a color.\n *\n * @param clr - The color to extract from\n * @returns Green component value (0-255)\n *\n * @example\n * ```typescript\n * color.g(color.rgb(255, 128, 64)) // Returns: 128\n * color.g(color.from_hex(\"#00FF00\")) // Returns: 255\n * color.g(color.from_hex(\"#FFA500\")) // Returns: 165 (orange)\n * ```\n */\nexport function g(clr: color): int {\n return parseColor(clr).g;\n}\n\n/**\n * Extracts the blue component from a color.\n *\n * @param clr - The color to extract from\n * @returns Blue component value (0-255)\n *\n * @example\n * ```typescript\n * color.b(color.rgb(255, 128, 64)) // Returns: 64\n * color.b(color.from_hex(\"#0000FF\")) // Returns: 255\n * color.b(color.from_hex(\"#FFA500\")) // Returns: 0 (orange)\n * ```\n */\nexport function b(clr: color): int {\n return parseColor(clr).b;\n}\n\n/**\n * Extracts the transparency component from a color.\n *\n * @param clr - The color to extract from\n * @returns Transparency value (0-100). 0 = fully opaque, 100 = fully transparent\n *\n * @remarks\n * - Returns 0 for colors without transparency (rgb format)\n * - Converts alpha channel (0-1) to transparency (0-100)\n * - PineScript stores the alpha as a byte (0-255) and returns an integer transparency:\n * `color.t(color.new(c, 33.3))` is 33\n *\n * @example\n * ```typescript\n * color.t(color.rgb(255, 0, 0)) // Returns: 0 (opaque)\n * color.t(color.rgb(255, 0, 0, 50)) // Returns: 50\n * color.t(color.rgb(255, 0, 0, 100)) // Returns: 100 (fully transparent)\n * ```\n */\nexport function t(clr: color): float {\n return Math.round((1 - alphaByte(parseColor(clr).a) / 255) * 100);\n}\n\n// Predefined color constants of PineScript v6.\n// PineScript v5 differs for red (#FF5252), teal (#00897B) and yellow (#FFEB3B).\n/**\n * Aqua/Cyan color constant\n * @constant {string} #00BCD4 - RGB(0, 188, 212)\n */\nexport const aqua = '#00BCD4';\n\n/**\n * Black color constant\n * @constant {string} #363A45 - RGB(54, 58, 69)\n */\nexport const black = '#363A45';\n\n/**\n * Blue color constant\n * @constant {string} #2962FF - RGB(41, 98, 255)\n */\nexport const blue = '#2962FF';\n\n/**\n * Fuchsia/Magenta color constant\n * @constant {string} #E040FB - RGB(224, 64, 251)\n */\nexport const fuchsia = '#E040FB';\n\n/**\n * Gray color constant\n * @constant {string} #787B86 - RGB(120, 123, 134)\n */\nexport const gray = '#787B86';\n\n/**\n * Green color constant (same as lime)\n * @constant {string} #4CAF50 - RGB(76, 175, 80)\n */\nexport const green = '#4CAF50';\n\n/**\n * Lime color constant (same as green)\n * @constant {string} #00E676 - RGB(0, 230, 118)\n */\nexport const lime = '#00E676';\n\n/**\n * Maroon color constant\n * @constant {string} #880E4F - RGB(136, 14, 79)\n */\nexport const maroon = '#880E4F';\n\n/**\n * Navy color constant\n * @constant {string} #311B92 - RGB(49, 27, 146)\n */\nexport const navy = '#311B92';\n\n/**\n * Olive color constant\n * @constant {string} #808000 - RGB(128, 128, 0)\n */\nexport const olive = '#808000';\n\n/**\n * Orange color constant\n * @constant {string} #FF9800 - RGB(255, 152, 0)\n */\nexport const orange = '#FF9800';\n\n/**\n * Purple color constant\n * @constant {string} #9C27B0 - RGB(156, 39, 176)\n */\nexport const purple = '#9C27B0';\n\n/**\n * Red color constant\n * @constant {string} #F23645 - RGB(242, 54, 69)\n */\nexport const red = '#F23645';\n\n/**\n * Silver color constant\n * @constant {string} #B2B5BE - RGB(178, 181, 190)\n */\nexport const silver = '#B2B5BE';\n\n/**\n * Teal color constant\n * @constant {string} #089981 - RGB(8, 153, 129)\n */\nexport const teal = '#089981';\n\n/**\n * White color constant\n * @constant {string} #FFFFFF - RGB(255, 255, 255)\n */\nexport const white = '#FFFFFF';\n\n/**\n * Yellow color constant\n * @constant {string} #FDD835 - RGB(253, 216, 53)\n */\nexport const yellow = '#FDD835';\n\n/**\n * Creates a color from a gradient based on value position.\n *\n * @param value - Value to calculate position-dependent color\n * @param bottom_value - Bottom position value corresponding to bottom_color\n * @param top_value - Top position value corresponding to top_color\n * @param bottom_color - Bottom position color\n * @param top_color - Top position color\n * @returns Color calculated from linear gradient\n *\n * @remarks\n * PineScript rules:\n * - If value <= bottom_value, returns bottom_color; else if value >= top_value, returns top_color\n * - An inverted range (bottom_value > top_value) returns bottom_color, wherever the value is\n * - Otherwise the colours are mixed with their transparency (premultiplied alpha, alpha as a byte); the RGB channels\n * and the alpha are truncated. PineScript's float rounding order is not known: a channel can differ by 1 when the\n * exact result is an integer (same RGB at both ends)\n * - An na value or bottom_value / top_value, or bottom_value == top_value, gives a fully transparent colour\n * - An na colour counts as fully transparent\n * - Works with rgb(), rgba() and hex (#RRGGBB, #RRGGBBAA) colours\n *\n * @example\n * ```typescript\n * // Value at middle of range gets middle color\n * const midColor = color.from_gradient(50, 0, 100,\n * color.rgb(255, 0, 0), // Red at bottom\n * color.rgb(0, 255, 0) // Green at top\n * ); // Returns color between red and green\n *\n * // Value at extremes\n * const lowColor = color.from_gradient(-10, 0, 100, red, green); // Returns red\n * const highColor = color.from_gradient(150, 0, 100, red, green); // Returns green\n * ```\n */\nexport function from_gradient(\n value: float,\n bottom_value: float,\n top_value: float,\n bottom_color: color,\n top_color: color\n): string {\n const transparent = 'rgba(0, 0, 0, 0)';\n if ([value, bottom_value, top_value].some((v) => v === null || v === undefined || Number.isNaN(v)) || bottom_value === top_value) {\n return transparent;\n }\n const k =\n value <= bottom_value || bottom_value > top_value\n ? 0\n : value >= top_value\n ? 1\n : (value - bottom_value) / (top_value - bottom_value);\n // alpha as a byte (0-255), as PineScript stores it; an na colour (null / undefined) is fully transparent\n const rgba = (c: color) => {\n if (c === null || c === undefined) return { r: 0, g: 0, b: 0, a: 0 };\n const p = parseColor(c);\n return { r: p.r, g: p.g, b: p.b, a: alphaByte(p.a) };\n };\n const c1 = rgba(bottom_color);\n const c2 = rgba(top_color);\n const a = c1.a * (1 - k) + c2.a * k;\n if (a === 0) return transparent;\n // operation order with the fewest differences to PineScript (channels as 0-1, alpha as a byte)\n const mix = (x1: number, x2: number) => Math.floor((((x1 / 255) * c1.a) * (1 - k) + ((x2 / 255) * c2.a) * k) / (a / 255));\n const [r, g, b] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];\n const alpha = Math.floor(a);\n return alpha === 255 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${alpha / 255})`;\n}\n\n/**\n * Alias for new_color function.\n * Creates a new color with specified transparency from an existing color.\n *\n * @param baseColor - The base color\n * @param transp - Transparency value (0-100). 0 = fully opaque, 100 = fully transparent\n * @returns New color with applied transparency\n *\n * @remarks\n * This is an alias for `new_color()` to match PineScript's `color.new()` syntax.\n *\n * @example\n * ```typescript\n * const redColor = color.rgb(255, 0, 0);\n * const transparentRed = color.new(redColor, 50); // 50% transparent red\n * ```\n */\nexport { new_color as new };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["red", "green", "blue", "r", "g", "b"]
|
|
7
7
|
}
|