@odoo/o-spreadsheet 14.0.1 → 14.0.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/o_spreadsheet.cjs.js +17836 -0
- package/dist/o_spreadsheet.d.ts +4102 -0
- package/dist/o_spreadsheet.esm.js +17801 -0
- package/dist/o_spreadsheet.iife.js +17838 -0
- package/dist/o_spreadsheet.iife.min.js +1440 -0
- package/package.json +27 -7
- package/readme.md +10 -0
- package/.eslintrc.json +0 -20
- package/.husky/post-checkout +0 -9
- package/.husky/pre-commit +0 -39
- package/.prettierignore +0 -1
- package/astToFormula.patch +0 -0
- package/demo/data.js +0 -255
- package/demo/index.html +0 -9
- package/demo/libs/Chart.bundle.js +0 -20755
- package/demo/main.js +0 -101
- package/doc/readme.md +0 -46
- package/rollup.config.js +0 -23
- package/src/base_plugin.ts +0 -102
- package/src/components/autofill.ts +0 -146
- package/src/components/bottom_bar.ts +0 -199
- package/src/components/color_picker.ts +0 -150
- package/src/components/composer/autocomplete_dropdown.ts +0 -135
- package/src/components/composer/composer.ts +0 -487
- package/src/components/composer/content_editable_helper.ts +0 -146
- package/src/components/figures/chart.ts +0 -70
- package/src/components/figures/container.ts +0 -268
- package/src/components/figures/text_figure.ts +0 -36
- package/src/components/grid.ts +0 -635
- package/src/components/helpers/dom_helpers.ts +0 -7
- package/src/components/helpers/drag_and_drop.ts +0 -17
- package/src/components/icons.ts +0 -36
- package/src/components/index.ts +0 -1
- package/src/components/menu.ts +0 -288
- package/src/components/overlay.ts +0 -457
- package/src/components/scrollbar.ts +0 -22
- package/src/components/selection_input.ts +0 -168
- package/src/components/side_panel/cell_is_rule_editor.ts +0 -169
- package/src/components/side_panel/chart_panel.ts +0 -104
- package/src/components/side_panel/color_scale_rule_editor.ts +0 -145
- package/src/components/side_panel/conditional_formatting.ts +0 -396
- package/src/components/side_panel/side_panel.ts +0 -127
- package/src/components/side_panel/translations_terms.ts +0 -45
- package/src/components/spreadsheet.ts +0 -198
- package/src/components/top_bar.ts +0 -535
- package/src/constants.ts +0 -26
- package/src/data.ts +0 -149
- package/src/fonts.ts +0 -41
- package/src/formulas/compiler.ts +0 -258
- package/src/formulas/composer_tokenizer.ts +0 -70
- package/src/formulas/index.ts +0 -15
- package/src/formulas/normalize.ts +0 -52
- package/src/formulas/parser.ts +0 -280
- package/src/formulas/range_tokenizer.ts +0 -97
- package/src/formulas/tokenizer.ts +0 -242
- package/src/functions/arguments.ts +0 -114
- package/src/functions/dates.ts +0 -302
- package/src/functions/helpers.ts +0 -592
- package/src/functions/index.ts +0 -52
- package/src/functions/module_database.ts +0 -282
- package/src/functions/module_date.ts +0 -743
- package/src/functions/module_info.ts +0 -69
- package/src/functions/module_logical.ts +0 -208
- package/src/functions/module_lookup.ts +0 -185
- package/src/functions/module_math.ts +0 -1252
- package/src/functions/module_operators.ts +0 -291
- package/src/functions/module_statistical.ts +0 -882
- package/src/functions/module_text.ts +0 -370
- package/src/helpers/color.ts +0 -30
- package/src/helpers/coordinates.ts +0 -71
- package/src/helpers/grid_manipulation.ts +0 -68
- package/src/helpers/index.ts +0 -7
- package/src/helpers/misc.ts +0 -76
- package/src/helpers/numbers.ts +0 -117
- package/src/helpers/uuid.ts +0 -19
- package/src/helpers/zones.ts +0 -263
- package/src/history.ts +0 -186
- package/src/index.ts +0 -84
- package/src/model.ts +0 -261
- package/src/plugins/autofill.ts +0 -412
- package/src/plugins/chart.ts +0 -404
- package/src/plugins/clipboard.ts +0 -461
- package/src/plugins/conditional_format.ts +0 -445
- package/src/plugins/core.ts +0 -1502
- package/src/plugins/edition.ts +0 -157
- package/src/plugins/evaluation.ts +0 -428
- package/src/plugins/figures.ts +0 -123
- package/src/plugins/formatting.ts +0 -630
- package/src/plugins/highlight.ts +0 -187
- package/src/plugins/index.ts +0 -32
- package/src/plugins/merge.ts +0 -524
- package/src/plugins/renderer.ts +0 -571
- package/src/plugins/selection.ts +0 -562
- package/src/plugins/selection_inputs.ts +0 -326
- package/src/registries/autofill_modifiers.ts +0 -76
- package/src/registries/autofill_rules.ts +0 -98
- package/src/registries/figure_registry.ts +0 -30
- package/src/registries/index.ts +0 -7
- package/src/registries/menu_items_registry.ts +0 -110
- package/src/registries/menus/cell_menu_registry.ts +0 -79
- package/src/registries/menus/col_menu_registry.ts +0 -63
- package/src/registries/menus/index.ts +0 -6
- package/src/registries/menus/menu_items_actions.ts +0 -425
- package/src/registries/menus/row_menu_registry.ts +0 -63
- package/src/registries/menus/sheet_menu_registry.ts +0 -75
- package/src/registries/menus/topbar_menu_registry.ts +0 -204
- package/src/registries/side_panel_registry.ts +0 -26
- package/src/registries/topbar_component_registry.ts +0 -12
- package/src/registry.ts +0 -51
- package/src/translation.ts +0 -44
- package/src/types/autofill.ts +0 -48
- package/src/types/chart.ts +0 -26
- package/src/types/commands.ts +0 -716
- package/src/types/conditional_formatting.ts +0 -124
- package/src/types/env.ts +0 -13
- package/src/types/functions.ts +0 -35
- package/src/types/getters.ts +0 -103
- package/src/types/index.ts +0 -20
- package/src/types/misc.ts +0 -143
- package/src/types/rendering.ts +0 -41
- package/src/types/workbook_data.ts +0 -62
- package/tests/__mocks__/uuid.ts +0 -7
- package/tests/canvas.mock.ts +0 -34
- package/tests/components/__mocks__/content_editable_helper.ts +0 -79
- package/tests/components/__mocks__/scrollbar.ts +0 -18
- package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +0 -29
- package/tests/components/__snapshots__/bottom_bar_test.ts.snap +0 -75
- package/tests/components/__snapshots__/context_menu_test.ts.snap +0 -88
- package/tests/components/__snapshots__/grid_test.ts.snap +0 -60
- package/tests/components/__snapshots__/spreadsheet_test.ts.snap +0 -455
- package/tests/components/__snapshots__/top_bar_test.ts.snap +0 -705
- package/tests/components/autocomplete_dropdown_test.ts +0 -315
- package/tests/components/autofill_test.ts +0 -167
- package/tests/components/bottom_bar_test.ts +0 -262
- package/tests/components/chart_side_panel_test.ts +0 -123
- package/tests/components/composer_test.ts +0 -400
- package/tests/components/context_menu_test.ts +0 -825
- package/tests/components/grid_manipulation_test.ts +0 -163
- package/tests/components/grid_test.ts +0 -581
- package/tests/components/overlay_test.ts +0 -541
- package/tests/components/selection_input_test.ts +0 -259
- package/tests/components/side_panel_test.ts +0 -148
- package/tests/components/spreadsheet_test.ts +0 -194
- package/tests/components/top_bar_test.ts +0 -427
- package/tests/data_test.ts +0 -175
- package/tests/dom_helper.ts +0 -42
- package/tests/formulas/__snapshots__/compiler_test.ts.snap +0 -302
- package/tests/formulas/compiler_test.ts +0 -266
- package/tests/formulas/composer_tokenizer_test.ts +0 -137
- package/tests/formulas/expressions_test.ts +0 -57
- package/tests/formulas/formulas_test.ts +0 -80
- package/tests/formulas/normalize_test.ts +0 -82
- package/tests/formulas/parser_test.ts +0 -224
- package/tests/formulas/range_tokenizer_test.ts +0 -187
- package/tests/formulas/tokenizer_test.ts +0 -164
- package/tests/functions/arguments_test.ts +0 -141
- package/tests/functions/dates_test.ts +0 -1081
- package/tests/functions/functions_test.ts +0 -53
- package/tests/functions/helper_test.ts +0 -98
- package/tests/functions/module_database_test.ts +0 -311
- package/tests/functions/module_date_test.ts +0 -941
- package/tests/functions/module_info_test.ts +0 -139
- package/tests/functions/module_logical_test.ts +0 -369
- package/tests/functions/module_lookup_test.ts +0 -541
- package/tests/functions/module_math_test.ts +0 -2482
- package/tests/functions/module_operators_test.ts +0 -955
- package/tests/functions/module_statistical_test.ts +0 -2014
- package/tests/functions/module_text_test.ts +0 -667
- package/tests/helpers/coordinates_test.ts +0 -25
- package/tests/helpers/misc_test.ts +0 -95
- package/tests/helpers/numbers_test.ts +0 -196
- package/tests/helpers/zones_test.ts +0 -97
- package/tests/helpers.ts +0 -384
- package/tests/menu_items_registry_test.ts +0 -540
- package/tests/model/plugins/__snapshots__/chart_test.ts.snap +0 -90
- package/tests/model/plugins/chart_test.ts +0 -562
- package/tests/model_test.ts +0 -82
- package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +0 -131
- package/tests/plugins/__snapshots__/renderer_test.ts.snap +0 -371
- package/tests/plugins/autofill_test.ts +0 -457
- package/tests/plugins/borders_test.ts +0 -295
- package/tests/plugins/clipboard_test.ts +0 -1180
- package/tests/plugins/conditional_formatting_test.ts +0 -1253
- package/tests/plugins/core_test.ts +0 -614
- package/tests/plugins/edition_test.ts +0 -100
- package/tests/plugins/evaluation_async_test.ts +0 -332
- package/tests/plugins/evaluation_dates_test.ts +0 -79
- package/tests/plugins/evaluation_test.ts +0 -901
- package/tests/plugins/figures_test.ts +0 -327
- package/tests/plugins/formatting_test.ts +0 -391
- package/tests/plugins/grid_manipulation_test.ts +0 -1366
- package/tests/plugins/highlight_test.ts +0 -413
- package/tests/plugins/history_test.ts +0 -142
- package/tests/plugins/import_export_test.ts +0 -276
- package/tests/plugins/merges_test.ts +0 -490
- package/tests/plugins/navigation_test.ts +0 -181
- package/tests/plugins/plugins/evaluation_test.ts +0 -111
- package/tests/plugins/renderer_test.ts +0 -598
- package/tests/plugins/resizing_test.ts +0 -152
- package/tests/plugins/selection_input_test.ts +0 -409
- package/tests/plugins/selection_test.ts +0 -442
- package/tests/plugins/sheets_test.ts +0 -643
- package/tests/plugins/style_test.ts +0 -90
- package/tsconfig.json +0 -22
|
@@ -1,1252 +0,0 @@
|
|
|
1
|
-
import { _lt } from "../translation";
|
|
2
|
-
import { FunctionDescription } from "../types";
|
|
3
|
-
import { args } from "./arguments";
|
|
4
|
-
import {
|
|
5
|
-
reduceArgs,
|
|
6
|
-
reduceNumbers,
|
|
7
|
-
strictToNumber,
|
|
8
|
-
toNumber,
|
|
9
|
-
toString,
|
|
10
|
-
visitMatchingRanges,
|
|
11
|
-
} from "./helpers";
|
|
12
|
-
|
|
13
|
-
// -----------------------------------------------------------------------------
|
|
14
|
-
// ACOS
|
|
15
|
-
// -----------------------------------------------------------------------------
|
|
16
|
-
export const ACOS: FunctionDescription = {
|
|
17
|
-
description: _lt("Inverse cosine of a value, in radians."),
|
|
18
|
-
args: args(`
|
|
19
|
-
value (number) ${_lt(
|
|
20
|
-
"The value for which to calculate the inverse cosine. Must be between -1 and 1, inclusive."
|
|
21
|
-
)}
|
|
22
|
-
`),
|
|
23
|
-
returns: ["NUMBER"],
|
|
24
|
-
compute: function (value: any): number {
|
|
25
|
-
const _value = toNumber(value);
|
|
26
|
-
if (Math.abs(_value) > 1) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
_lt(
|
|
29
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %s. Valid values are between -1 and 1 inclusive.",
|
|
30
|
-
_value.toString()
|
|
31
|
-
)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
return Math.acos(_value);
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// -----------------------------------------------------------------------------
|
|
39
|
-
// ACOSH
|
|
40
|
-
// -----------------------------------------------------------------------------
|
|
41
|
-
export const ACOSH: FunctionDescription = {
|
|
42
|
-
description: _lt("Inverse hyperbolic cosine of a number."),
|
|
43
|
-
args: args(`
|
|
44
|
-
value (number) ${_lt(
|
|
45
|
-
"The value for which to calculate the inverse hyperbolic cosine. Must be greater than or equal to 1."
|
|
46
|
-
)}
|
|
47
|
-
`),
|
|
48
|
-
returns: ["NUMBER"],
|
|
49
|
-
compute: function (value: any): number {
|
|
50
|
-
const _value = toNumber(value);
|
|
51
|
-
if (_value < 1) {
|
|
52
|
-
throw new Error(
|
|
53
|
-
_lt(
|
|
54
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %s. It should be greater than or equal to 1.",
|
|
55
|
-
_value.toString()
|
|
56
|
-
)
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
return Math.acosh(_value);
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// -----------------------------------------------------------------------------
|
|
64
|
-
// ACOT
|
|
65
|
-
// -----------------------------------------------------------------------------
|
|
66
|
-
export const ACOT: FunctionDescription = {
|
|
67
|
-
description: _lt("Inverse cotangent of a value."),
|
|
68
|
-
args: args(`
|
|
69
|
-
value (number) ${_lt("The value for which to calculate the inverse cotangent.")}
|
|
70
|
-
`),
|
|
71
|
-
returns: ["NUMBER"],
|
|
72
|
-
compute: function (value: any): number {
|
|
73
|
-
const _value = toNumber(value);
|
|
74
|
-
const sign = Math.sign(_value) || 1;
|
|
75
|
-
// ACOT has two possible configurations:
|
|
76
|
-
// @compatibility Excel: return Math.PI / 2 - Math.atan(toNumber(_value));
|
|
77
|
-
// @compatibility Google: return sign * Math.PI / 2 - Math.atan(toNumber(_value));
|
|
78
|
-
return (sign * Math.PI) / 2 - Math.atan(_value);
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
// -----------------------------------------------------------------------------
|
|
83
|
-
// ACOTH
|
|
84
|
-
// -----------------------------------------------------------------------------
|
|
85
|
-
export const ACOTH: FunctionDescription = {
|
|
86
|
-
description: _lt("Inverse hyperbolic cotangent of a value."),
|
|
87
|
-
args: args(`
|
|
88
|
-
value (number) ${_lt(
|
|
89
|
-
"The value for which to calculate the inverse hyperbolic cotangent. Must not be between -1 and 1, inclusive."
|
|
90
|
-
)}
|
|
91
|
-
`),
|
|
92
|
-
returns: ["NUMBER"],
|
|
93
|
-
compute: function (value: any): number {
|
|
94
|
-
const _value = toNumber(value);
|
|
95
|
-
if (Math.abs(_value) <= 1) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
_lt(
|
|
98
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %s. Valid values cannot be between -1 and 1 inclusive.",
|
|
99
|
-
_value.toString()
|
|
100
|
-
)
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return Math.log((_value + 1) / (_value - 1)) / 2;
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
// -----------------------------------------------------------------------------
|
|
108
|
-
// ASIN
|
|
109
|
-
// -----------------------------------------------------------------------------
|
|
110
|
-
export const ASIN: FunctionDescription = {
|
|
111
|
-
description: _lt("Inverse sine of a value, in radians."),
|
|
112
|
-
args: args(`
|
|
113
|
-
value (number) ${_lt(
|
|
114
|
-
"The value for which to calculate the inverse sine. Must be between -1 and 1, inclusive."
|
|
115
|
-
)}
|
|
116
|
-
`),
|
|
117
|
-
returns: ["NUMBER"],
|
|
118
|
-
compute: function (value: any): number {
|
|
119
|
-
const _value = toNumber(value);
|
|
120
|
-
if (Math.abs(_value) > 1) {
|
|
121
|
-
throw new Error(
|
|
122
|
-
_lt(
|
|
123
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %S. Valid values are between -1 and 1 inclusive.",
|
|
124
|
-
_value.toString()
|
|
125
|
-
)
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
return Math.asin(_value);
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
// -----------------------------------------------------------------------------
|
|
133
|
-
// ASINH
|
|
134
|
-
// -----------------------------------------------------------------------------
|
|
135
|
-
export const ASINH: FunctionDescription = {
|
|
136
|
-
description: _lt("Inverse hyperbolic sine of a number."),
|
|
137
|
-
args: args(`
|
|
138
|
-
value (number) ${_lt("The value for which to calculate the inverse hyperbolic sine.")}
|
|
139
|
-
`),
|
|
140
|
-
returns: ["NUMBER"],
|
|
141
|
-
compute: function (value: any): number {
|
|
142
|
-
return Math.asinh(toNumber(value));
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// -----------------------------------------------------------------------------
|
|
147
|
-
// ATAN
|
|
148
|
-
// -----------------------------------------------------------------------------
|
|
149
|
-
export const ATAN: FunctionDescription = {
|
|
150
|
-
description: _lt("Inverse tangent of a value, in radians."),
|
|
151
|
-
args: args(`
|
|
152
|
-
value (number) ${_lt("The value for which to calculate the inverse tangent.")}
|
|
153
|
-
`),
|
|
154
|
-
returns: ["NUMBER"],
|
|
155
|
-
compute: function (value: any): number {
|
|
156
|
-
return Math.atan(toNumber(value));
|
|
157
|
-
},
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// -----------------------------------------------------------------------------
|
|
161
|
-
// ATAN2
|
|
162
|
-
// -----------------------------------------------------------------------------
|
|
163
|
-
export const ATAN2: FunctionDescription = {
|
|
164
|
-
description: _lt("Angle from the X axis to a point (x,y), in radians."),
|
|
165
|
-
args: args(`
|
|
166
|
-
x (number) ${_lt(
|
|
167
|
-
"The x coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis."
|
|
168
|
-
)}
|
|
169
|
-
y (number) ${_lt(
|
|
170
|
-
"The y coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis."
|
|
171
|
-
)}
|
|
172
|
-
`),
|
|
173
|
-
returns: ["NUMBER"],
|
|
174
|
-
compute: function (x: any, y: any): number {
|
|
175
|
-
const _x = toNumber(x);
|
|
176
|
-
const _y = toNumber(y);
|
|
177
|
-
if (_x === 0 && _y === 0) {
|
|
178
|
-
throw new Error(_lt(`Function [[FUNCTION_NAME]] caused a divide by zero error.`));
|
|
179
|
-
}
|
|
180
|
-
return Math.atan2(_y, _x);
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
// -----------------------------------------------------------------------------
|
|
185
|
-
// ATANH
|
|
186
|
-
// -----------------------------------------------------------------------------
|
|
187
|
-
export const ATANH: FunctionDescription = {
|
|
188
|
-
description: _lt("Inverse hyperbolic tangent of a number."),
|
|
189
|
-
args: args(`
|
|
190
|
-
value (number) ${_lt(
|
|
191
|
-
"The value for which to calculate the inverse hyperbolic tangent. Must be between -1 and 1, exclusive."
|
|
192
|
-
)}
|
|
193
|
-
`),
|
|
194
|
-
returns: ["NUMBER"],
|
|
195
|
-
compute: function (value: any): number {
|
|
196
|
-
const _value = toNumber(value);
|
|
197
|
-
if (Math.abs(_value) >= 1) {
|
|
198
|
-
throw new Error(
|
|
199
|
-
_lt(
|
|
200
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %s. Valid values are between -1 and 1 exclusive.",
|
|
201
|
-
_value.toString()
|
|
202
|
-
)
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
return Math.atanh(_value);
|
|
206
|
-
},
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
// -----------------------------------------------------------------------------
|
|
210
|
-
// CEILING
|
|
211
|
-
// -----------------------------------------------------------------------------
|
|
212
|
-
export const CEILING: FunctionDescription = {
|
|
213
|
-
description: _lt(`Rounds number up to nearest multiple of factor.`),
|
|
214
|
-
args: args(`
|
|
215
|
-
value (number) ${_lt("The value to round up to the nearest integer multiple of factor.")}
|
|
216
|
-
factor (number, optional, default=1) ${_lt(
|
|
217
|
-
"The number to whose multiples value will be rounded."
|
|
218
|
-
)}
|
|
219
|
-
`),
|
|
220
|
-
returns: ["NUMBER"],
|
|
221
|
-
compute: function (value: any, factor: any = 1): number {
|
|
222
|
-
const _value = toNumber(value);
|
|
223
|
-
const _factor = toNumber(factor);
|
|
224
|
-
|
|
225
|
-
if (_value > 0 && _factor < 0) {
|
|
226
|
-
throw new Error(
|
|
227
|
-
_lt(
|
|
228
|
-
"Function CEILING expects the parameter '%s' to be positive when parameter '%s' is positive. Change '%s' from [%s] to a positive value.",
|
|
229
|
-
CEILING.args[1].name,
|
|
230
|
-
CEILING.args[0].name,
|
|
231
|
-
CEILING.args[1].name,
|
|
232
|
-
_factor.toString()
|
|
233
|
-
)
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
return _factor ? Math.ceil(_value / _factor) * _factor : 0;
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// -----------------------------------------------------------------------------
|
|
241
|
-
// CEILING.MATH
|
|
242
|
-
// -----------------------------------------------------------------------------
|
|
243
|
-
export const CEILING_MATH: FunctionDescription = {
|
|
244
|
-
description: _lt(`Rounds number up to nearest multiple of factor.`),
|
|
245
|
-
args: args(`
|
|
246
|
-
number (number) ${_lt("The value to round up to the nearest integer multiple of significance.")}
|
|
247
|
-
significance (number, optional, default=1) ${_lt(
|
|
248
|
-
"The number to whose multiples number will be rounded. The sign of significance will be ignored."
|
|
249
|
-
)}
|
|
250
|
-
mode (number, optional, default=0) ${_lt(
|
|
251
|
-
"If number is negative, specifies the rounding direction. If 0 or blank, it is rounded towards zero. Otherwise, it is rounded away from zero."
|
|
252
|
-
)}
|
|
253
|
-
`),
|
|
254
|
-
returns: ["NUMBER"],
|
|
255
|
-
compute: function (number: any, significance: any = 1, mode: any = 0): number {
|
|
256
|
-
let _significance = toNumber(significance);
|
|
257
|
-
if (_significance === 0) {
|
|
258
|
-
return 0;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const _number = toNumber(number);
|
|
262
|
-
_significance = Math.abs(_significance);
|
|
263
|
-
if (_number >= 0) {
|
|
264
|
-
return Math.ceil(_number / _significance) * _significance;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const _mode = toNumber(mode);
|
|
268
|
-
if (_mode === 0) {
|
|
269
|
-
return -Math.floor(Math.abs(_number) / _significance) * _significance;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return -Math.ceil(Math.abs(_number) / _significance) * _significance;
|
|
273
|
-
},
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
// -----------------------------------------------------------------------------
|
|
277
|
-
// CEILING.PRECISE
|
|
278
|
-
// -----------------------------------------------------------------------------
|
|
279
|
-
export const CEILING_PRECISE: FunctionDescription = {
|
|
280
|
-
description: _lt(`Rounds number up to nearest multiple of factor.`),
|
|
281
|
-
args: args(`
|
|
282
|
-
number (number) ${_lt("The value to round up to the nearest integer multiple of significance.")}
|
|
283
|
-
significance (number, optional, default=1) ${_lt(
|
|
284
|
-
"The number to whose multiples number will be rounded."
|
|
285
|
-
)}
|
|
286
|
-
`),
|
|
287
|
-
returns: ["NUMBER"],
|
|
288
|
-
compute: function (number: any, significance: any): number {
|
|
289
|
-
return CEILING_MATH.compute(number, significance, 0);
|
|
290
|
-
},
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
// -----------------------------------------------------------------------------
|
|
294
|
-
// COS
|
|
295
|
-
// -----------------------------------------------------------------------------
|
|
296
|
-
export const COS: FunctionDescription = {
|
|
297
|
-
description: _lt("Cosine of an angle provided in radians."),
|
|
298
|
-
args: args(`
|
|
299
|
-
angle (number) ${_lt("The angle to find the cosine of, in radians.")}
|
|
300
|
-
`),
|
|
301
|
-
returns: ["NUMBER"],
|
|
302
|
-
compute: function (angle: any): number {
|
|
303
|
-
return Math.cos(toNumber(angle));
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
// -----------------------------------------------------------------------------
|
|
308
|
-
// COSH
|
|
309
|
-
// -----------------------------------------------------------------------------
|
|
310
|
-
export const COSH: FunctionDescription = {
|
|
311
|
-
description: _lt("Hyperbolic cosine of any real number."),
|
|
312
|
-
args: args(`
|
|
313
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic cosine of.")}
|
|
314
|
-
`),
|
|
315
|
-
returns: ["NUMBER"],
|
|
316
|
-
compute: function (value: any): number {
|
|
317
|
-
return Math.cosh(toNumber(value));
|
|
318
|
-
},
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
// -----------------------------------------------------------------------------
|
|
322
|
-
// COT
|
|
323
|
-
// -----------------------------------------------------------------------------
|
|
324
|
-
export const COT: FunctionDescription = {
|
|
325
|
-
description: _lt("Cotangent of an angle provided in radians."),
|
|
326
|
-
args: args(`
|
|
327
|
-
angle (number) ${_lt("The angle to find the cotangent of, in radians.")}
|
|
328
|
-
`),
|
|
329
|
-
returns: ["NUMBER"],
|
|
330
|
-
compute: function (angle: any): number {
|
|
331
|
-
const _angle = toNumber(angle);
|
|
332
|
-
if (_angle === 0) {
|
|
333
|
-
throw new Error(
|
|
334
|
-
_lt(`Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error.`)
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
return 1 / Math.tan(_angle);
|
|
338
|
-
},
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
// -----------------------------------------------------------------------------
|
|
342
|
-
// COTH
|
|
343
|
-
// -----------------------------------------------------------------------------
|
|
344
|
-
export const COTH: FunctionDescription = {
|
|
345
|
-
description: _lt("Hyperbolic cotangent of any real number."),
|
|
346
|
-
args: args(`
|
|
347
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic cotangent of.")}
|
|
348
|
-
`),
|
|
349
|
-
returns: ["NUMBER"],
|
|
350
|
-
compute: function (value: any): number {
|
|
351
|
-
const _value = toNumber(value);
|
|
352
|
-
if (_value === 0) {
|
|
353
|
-
throw new Error(
|
|
354
|
-
_lt(`Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error.`)
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
return 1 / Math.tanh(_value);
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
// -----------------------------------------------------------------------------
|
|
362
|
-
// COUNTBLANK
|
|
363
|
-
// -----------------------------------------------------------------------------
|
|
364
|
-
export const COUNTBLANK: FunctionDescription = {
|
|
365
|
-
description: _lt("Number of empty values."),
|
|
366
|
-
args: args(`
|
|
367
|
-
value1 (any, range) ${_lt("The first value or range in which to count the number of blanks.")}
|
|
368
|
-
value2 (any, range, optional, repeating) ${_lt(
|
|
369
|
-
"Additional values or ranges in which to count the number of blanks."
|
|
370
|
-
)}
|
|
371
|
-
`),
|
|
372
|
-
returns: ["NUMBER"],
|
|
373
|
-
compute: function (): number {
|
|
374
|
-
return reduceArgs(
|
|
375
|
-
arguments,
|
|
376
|
-
(acc, a) => (a === null || a === undefined || a === "" ? acc + 1 : acc),
|
|
377
|
-
0
|
|
378
|
-
);
|
|
379
|
-
},
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
// -----------------------------------------------------------------------------
|
|
383
|
-
// COUNTIF
|
|
384
|
-
// -----------------------------------------------------------------------------
|
|
385
|
-
export const COUNTIF: FunctionDescription = {
|
|
386
|
-
description: _lt("A conditional count across a range."),
|
|
387
|
-
args: args(`
|
|
388
|
-
range (range) ${_lt("The range that is tested against criterion.")}
|
|
389
|
-
criterion (string) ${_lt("The pattern or test to apply to range.")}
|
|
390
|
-
`),
|
|
391
|
-
returns: ["NUMBER"],
|
|
392
|
-
compute: function (): number {
|
|
393
|
-
let count = 0;
|
|
394
|
-
visitMatchingRanges(arguments, (i, j) => {
|
|
395
|
-
count += 1;
|
|
396
|
-
});
|
|
397
|
-
return count;
|
|
398
|
-
},
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
// -----------------------------------------------------------------------------
|
|
402
|
-
// COUNTIFS
|
|
403
|
-
// -----------------------------------------------------------------------------
|
|
404
|
-
export const COUNTIFS: FunctionDescription = {
|
|
405
|
-
description: _lt("Count values depending on multiple criteria."),
|
|
406
|
-
args: args(`
|
|
407
|
-
criteria_range (range) ${_lt("The range to check against criterion1.")}
|
|
408
|
-
criterion (string) ${_lt("The pattern or test to apply to criteria_range1.")}
|
|
409
|
-
additional_values (any, range, optional, repeating) ${_lt(
|
|
410
|
-
"Additional criteria_range and criterion to check."
|
|
411
|
-
)}
|
|
412
|
-
`),
|
|
413
|
-
// @compatibility: on google sheets, args definitions are next:
|
|
414
|
-
// criteria_range1 (any, range) The range to check against criterion1.
|
|
415
|
-
// criterion1 (string) The pattern or test to apply to criteria_range1.
|
|
416
|
-
// criteria_range2 (any, range, optional repeating) Additional ranges over which to evaluate the additional criteria. The filtered set will be the intersection of the sets produced by each criterion-range pair.
|
|
417
|
-
// criterion2 (string, optional repeating) Additional criteria to check.
|
|
418
|
-
returns: ["NUMBER"],
|
|
419
|
-
compute: function (): number {
|
|
420
|
-
let count = 0;
|
|
421
|
-
visitMatchingRanges(arguments, (i, j) => {
|
|
422
|
-
count += 1;
|
|
423
|
-
});
|
|
424
|
-
return count;
|
|
425
|
-
},
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// -----------------------------------------------------------------------------
|
|
429
|
-
// COUNTUNIQUE
|
|
430
|
-
// -----------------------------------------------------------------------------
|
|
431
|
-
|
|
432
|
-
function isDefined(value: any): boolean {
|
|
433
|
-
switch (value) {
|
|
434
|
-
case undefined:
|
|
435
|
-
return false;
|
|
436
|
-
case "":
|
|
437
|
-
return false;
|
|
438
|
-
case null:
|
|
439
|
-
return false;
|
|
440
|
-
default:
|
|
441
|
-
return true;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
export const COUNTUNIQUE: FunctionDescription = {
|
|
446
|
-
description: _lt("Counts number of unique values in a range."),
|
|
447
|
-
args: args(`
|
|
448
|
-
value1 (any, range) ${_lt("The first value or range to consider for uniqueness.")}
|
|
449
|
-
value2 (any, range, optional, repeating) ${_lt(
|
|
450
|
-
"Additional values or ranges to consider for uniqueness."
|
|
451
|
-
)}
|
|
452
|
-
`),
|
|
453
|
-
returns: ["NUMBER"],
|
|
454
|
-
compute: function (): number {
|
|
455
|
-
return reduceArgs(arguments, (acc, a) => (isDefined(a) ? acc.add(a) : acc), new Set()).size;
|
|
456
|
-
},
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
// -----------------------------------------------------------------------------
|
|
460
|
-
// COUNTUNIQUEIFS
|
|
461
|
-
// -----------------------------------------------------------------------------
|
|
462
|
-
|
|
463
|
-
export const COUNTUNIQUEIFS: FunctionDescription = {
|
|
464
|
-
description: _lt("Counts number of unique values in a range, filtered by a set of criteria."),
|
|
465
|
-
args: args(`
|
|
466
|
-
range (range) ${_lt(
|
|
467
|
-
"The range of cells from which the number of unique values will be counted."
|
|
468
|
-
)}
|
|
469
|
-
criteria_range1 (range) ${_lt("The range of cells over which to evaluate criterion1.")}
|
|
470
|
-
criterion1 (string) ${_lt(
|
|
471
|
-
"The pattern or test to apply to criteria_range1, such that each cell that evaluates to TRUE will be included in the filtered set."
|
|
472
|
-
)}
|
|
473
|
-
additional_values (any, range, optional, repeating) ${_lt(
|
|
474
|
-
"Additional criteria_range and criterion to check."
|
|
475
|
-
)}
|
|
476
|
-
`),
|
|
477
|
-
// @compatibility: on google sheets, args definitions are next:
|
|
478
|
-
// range (any, range) The range of cells from which the number of unique values will be counted.
|
|
479
|
-
// criteria_range1 (any, range) The range of cells over which to evaluate criterion1.
|
|
480
|
-
// criterion1 (string) The pattern or test to apply to criteria_range1, such that each cell that evaluates to TRUE will be included in the filtered set.
|
|
481
|
-
// criteria_range2 (any, range, optional, repeating) Additional ranges over which to evaluate the additional criteria. The filtered set will be the intersection of the sets produced by each criterion-range pair.
|
|
482
|
-
// criterion2 (string, optional, repeating) The pattern or test to apply to criteria_range2.
|
|
483
|
-
returns: ["NUMBER"],
|
|
484
|
-
compute: function (range, ...args): number {
|
|
485
|
-
let uniqueValues = new Set();
|
|
486
|
-
visitMatchingRanges(args, (i, j) => {
|
|
487
|
-
const value = range[i][j];
|
|
488
|
-
if (isDefined(value)) {
|
|
489
|
-
uniqueValues.add(value);
|
|
490
|
-
}
|
|
491
|
-
});
|
|
492
|
-
return uniqueValues.size;
|
|
493
|
-
},
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
// -----------------------------------------------------------------------------
|
|
497
|
-
// CSC
|
|
498
|
-
// -----------------------------------------------------------------------------
|
|
499
|
-
export const CSC: FunctionDescription = {
|
|
500
|
-
description: _lt("Cosecant of an angle provided in radians."),
|
|
501
|
-
args: args(`
|
|
502
|
-
angle (number) ${_lt("The angle to find the cosecant of, in radians.")}
|
|
503
|
-
`),
|
|
504
|
-
returns: ["NUMBER"],
|
|
505
|
-
compute: function (angle: any): number {
|
|
506
|
-
const _angle = toNumber(angle);
|
|
507
|
-
if (_angle === 0) {
|
|
508
|
-
throw new Error(_lt(`Function [[FUNCTION_NAME]] caused a divide by zero error.`));
|
|
509
|
-
}
|
|
510
|
-
return 1 / Math.sin(_angle);
|
|
511
|
-
},
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
// -----------------------------------------------------------------------------
|
|
515
|
-
// CSCH
|
|
516
|
-
// -----------------------------------------------------------------------------
|
|
517
|
-
export const CSCH: FunctionDescription = {
|
|
518
|
-
description: _lt("Hyperbolic cosecant of any real number."),
|
|
519
|
-
args: args(`
|
|
520
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic cosecant of.")}
|
|
521
|
-
`),
|
|
522
|
-
returns: ["NUMBER"],
|
|
523
|
-
compute: function (value: any): number {
|
|
524
|
-
const _value = toNumber(value);
|
|
525
|
-
if (_value === 0) {
|
|
526
|
-
throw new Error(_lt(`Function [[FUNCTION_NAME]] caused a divide by zero error.`));
|
|
527
|
-
}
|
|
528
|
-
return 1 / Math.sinh(_value);
|
|
529
|
-
},
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
// -----------------------------------------------------------------------------
|
|
533
|
-
// DECIMAL
|
|
534
|
-
// -----------------------------------------------------------------------------
|
|
535
|
-
const decimalErrorParameter2 = (parameterName, base, value) =>
|
|
536
|
-
_lt(
|
|
537
|
-
"Function DECIMAL expects the parameter '%s' to be a valid base %s representation. Change '%s' from [%s] to a valid base %s representation.",
|
|
538
|
-
parameterName,
|
|
539
|
-
base,
|
|
540
|
-
parameterName,
|
|
541
|
-
value,
|
|
542
|
-
base
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
export const DECIMAL: FunctionDescription = {
|
|
546
|
-
description: _lt("Converts from another base to decimal."),
|
|
547
|
-
args: args(`
|
|
548
|
-
value (string) ${_lt("The number to convert.")},
|
|
549
|
-
base (number) ${_lt("The base to convert the value from.")},
|
|
550
|
-
`),
|
|
551
|
-
returns: ["NUMBER"],
|
|
552
|
-
compute: function (value: any, base: any): number {
|
|
553
|
-
let _base = toNumber(base);
|
|
554
|
-
_base = Math.floor(_base);
|
|
555
|
-
if (_base < 2 || _base > 36) {
|
|
556
|
-
throw new Error(
|
|
557
|
-
_lt(
|
|
558
|
-
"Function DECIMAL expects the parameter '%s' to be between 2 and 36 inclusive. Change '%s' from [%s] to a value between 2 and 36.",
|
|
559
|
-
DECIMAL.args[1].name,
|
|
560
|
-
DECIMAL.args[1].name,
|
|
561
|
-
_base.toString()
|
|
562
|
-
)
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
const _value = toString(value);
|
|
567
|
-
if (_value === "") {
|
|
568
|
-
return 0;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* @compatibility: on Google sheets, expects the parameter 'value' to be positive.
|
|
573
|
-
* Return error if 'value' is positive.
|
|
574
|
-
* Remove '-?' in the next regex to catch this error.
|
|
575
|
-
*/
|
|
576
|
-
if (!_value.match(/^-?[a-z0-9]+$/i)) {
|
|
577
|
-
throw new Error(decimalErrorParameter2(DECIMAL.args[0].name, _base, _value));
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
const deci = parseInt(_value, _base);
|
|
581
|
-
if (isNaN(deci)) {
|
|
582
|
-
throw new Error(decimalErrorParameter2(DECIMAL.args[0].name, _base, _value));
|
|
583
|
-
}
|
|
584
|
-
return deci;
|
|
585
|
-
},
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
// -----------------------------------------------------------------------------
|
|
589
|
-
// DEGREES
|
|
590
|
-
// -----------------------------------------------------------------------------
|
|
591
|
-
export const DEGREES: FunctionDescription = {
|
|
592
|
-
description: _lt(`Converts an angle value in radians to degrees.`),
|
|
593
|
-
args: args(`
|
|
594
|
-
angle (number) ${_lt("The angle to convert from radians to degrees.")}
|
|
595
|
-
`),
|
|
596
|
-
returns: ["NUMBER"],
|
|
597
|
-
compute: function (angle: any): number {
|
|
598
|
-
return (toNumber(angle) * 180) / Math.PI;
|
|
599
|
-
},
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
// -----------------------------------------------------------------------------
|
|
603
|
-
// EXP
|
|
604
|
-
// -----------------------------------------------------------------------------
|
|
605
|
-
export const EXP: FunctionDescription = {
|
|
606
|
-
description: _lt(`Euler's number, e (~2.718) raised to a power.`),
|
|
607
|
-
args: args(`
|
|
608
|
-
value (number) ${_lt("The exponent to raise e.")}
|
|
609
|
-
`),
|
|
610
|
-
returns: ["NUMBER"],
|
|
611
|
-
compute: function (value: any): number {
|
|
612
|
-
return Math.exp(toNumber(value));
|
|
613
|
-
},
|
|
614
|
-
};
|
|
615
|
-
|
|
616
|
-
// -----------------------------------------------------------------------------
|
|
617
|
-
// FLOOR
|
|
618
|
-
// -----------------------------------------------------------------------------
|
|
619
|
-
export const FLOOR: FunctionDescription = {
|
|
620
|
-
description: _lt(`Rounds number down to nearest multiple of factor.`),
|
|
621
|
-
args: args(`
|
|
622
|
-
value (number) ${_lt("The value to round down to the nearest integer multiple of factor.")}
|
|
623
|
-
factor (number, optional, default=1) ${_lt(
|
|
624
|
-
"The number to whose multiples value will be rounded."
|
|
625
|
-
)}
|
|
626
|
-
`),
|
|
627
|
-
returns: ["NUMBER"],
|
|
628
|
-
compute: function (value: any, factor: any = 1): number {
|
|
629
|
-
const _value = toNumber(value);
|
|
630
|
-
const _factor = toNumber(factor);
|
|
631
|
-
|
|
632
|
-
if (_value > 0 && _factor < 0) {
|
|
633
|
-
throw new Error(
|
|
634
|
-
_lt(
|
|
635
|
-
"Function FLOOR expects the parameter '%s' to be positive when parameter '%s' is positive. Change '%s' from [%s] to a positive value.",
|
|
636
|
-
FLOOR.args[1].name,
|
|
637
|
-
FLOOR.args[0].name,
|
|
638
|
-
FLOOR.args[1].name,
|
|
639
|
-
_factor.toString()
|
|
640
|
-
)
|
|
641
|
-
);
|
|
642
|
-
}
|
|
643
|
-
return _factor ? Math.floor(_value / _factor) * _factor : 0;
|
|
644
|
-
},
|
|
645
|
-
};
|
|
646
|
-
|
|
647
|
-
// -----------------------------------------------------------------------------
|
|
648
|
-
// FLOOR.MATH
|
|
649
|
-
// -----------------------------------------------------------------------------
|
|
650
|
-
export const FLOOR_MATH: FunctionDescription = {
|
|
651
|
-
description: _lt(`Rounds number down to nearest multiple of factor.`),
|
|
652
|
-
args: args(`
|
|
653
|
-
number (number) ${_lt(
|
|
654
|
-
"The value to round down to the nearest integer multiple of significance."
|
|
655
|
-
)}
|
|
656
|
-
significance (number, optional, default=1) ${_lt(
|
|
657
|
-
"The number to whose multiples number will be rounded. The sign of significance will be ignored."
|
|
658
|
-
)}
|
|
659
|
-
mode (number, optional, default=0) ${_lt(
|
|
660
|
-
"If number is negative, specifies the rounding direction. If 0 or blank, it is rounded away from zero. Otherwise, it is rounded towards zero."
|
|
661
|
-
)}
|
|
662
|
-
`),
|
|
663
|
-
returns: ["NUMBER"],
|
|
664
|
-
compute: function (number: any, significance: any = 1, mode: any = 0): number {
|
|
665
|
-
let _significance = toNumber(significance);
|
|
666
|
-
if (_significance === 0) {
|
|
667
|
-
return 0;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
const _number = toNumber(number);
|
|
671
|
-
_significance = Math.abs(_significance);
|
|
672
|
-
if (_number >= 0) {
|
|
673
|
-
return Math.floor(_number / _significance) * _significance;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
const _mode = toNumber(mode);
|
|
677
|
-
if (_mode === 0) {
|
|
678
|
-
return -Math.ceil(Math.abs(_number) / _significance) * _significance;
|
|
679
|
-
}
|
|
680
|
-
return -Math.floor(Math.abs(_number) / _significance) * _significance;
|
|
681
|
-
},
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
// -----------------------------------------------------------------------------
|
|
685
|
-
// FLOOR.PRECISE
|
|
686
|
-
// -----------------------------------------------------------------------------
|
|
687
|
-
export const FLOOR_PRECISE: FunctionDescription = {
|
|
688
|
-
description: _lt(`Rounds number down to nearest multiple of factor.`),
|
|
689
|
-
args: args(`
|
|
690
|
-
number (number) ${_lt(
|
|
691
|
-
"The value to round down to the nearest integer multiple of significance."
|
|
692
|
-
)}
|
|
693
|
-
significance (number, optional, default=1) ${_lt(
|
|
694
|
-
"The number to whose multiples number will be rounded."
|
|
695
|
-
)}
|
|
696
|
-
`),
|
|
697
|
-
returns: ["NUMBER"],
|
|
698
|
-
compute: function (number: number, significance: number = 1): number {
|
|
699
|
-
return FLOOR_MATH.compute(number, significance, 0);
|
|
700
|
-
},
|
|
701
|
-
};
|
|
702
|
-
|
|
703
|
-
// -----------------------------------------------------------------------------
|
|
704
|
-
// ISEVEN
|
|
705
|
-
// -----------------------------------------------------------------------------
|
|
706
|
-
export const ISEVEN: FunctionDescription = {
|
|
707
|
-
description: _lt(`Whether the provided value is even.`),
|
|
708
|
-
args: args(`
|
|
709
|
-
value (number) ${_lt("The value to be verified as even.")}
|
|
710
|
-
`),
|
|
711
|
-
returns: ["BOOLEAN"],
|
|
712
|
-
compute: function (value: any): boolean {
|
|
713
|
-
const _value = strictToNumber(value);
|
|
714
|
-
|
|
715
|
-
return Math.floor(Math.abs(_value)) & 1 ? false : true;
|
|
716
|
-
},
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
// -----------------------------------------------------------------------------
|
|
720
|
-
// ISO.CEILING
|
|
721
|
-
// -----------------------------------------------------------------------------
|
|
722
|
-
export const ISO_CEILING: FunctionDescription = {
|
|
723
|
-
description: _lt(`Rounds number up to nearest multiple of factor.`),
|
|
724
|
-
args: args(`
|
|
725
|
-
number (number) ${_lt(
|
|
726
|
-
"The value to round up to the nearest integer multiple of significance."
|
|
727
|
-
)}
|
|
728
|
-
significance (number, optional, default=1) ${_lt(
|
|
729
|
-
"The number to whose multiples number will be rounded."
|
|
730
|
-
)}
|
|
731
|
-
`),
|
|
732
|
-
returns: ["NUMBER"],
|
|
733
|
-
compute: function (number: any, significance: any): number {
|
|
734
|
-
return CEILING_MATH.compute(number, significance, 0);
|
|
735
|
-
},
|
|
736
|
-
};
|
|
737
|
-
|
|
738
|
-
// -----------------------------------------------------------------------------
|
|
739
|
-
// ISODD
|
|
740
|
-
// -----------------------------------------------------------------------------
|
|
741
|
-
export const ISODD: FunctionDescription = {
|
|
742
|
-
description: _lt(`Whether the provided value is even.`),
|
|
743
|
-
args: args(`
|
|
744
|
-
value (number) ${_lt("The value to be verified as even.")}
|
|
745
|
-
`),
|
|
746
|
-
returns: ["BOOLEAN"],
|
|
747
|
-
compute: function (value: any): boolean {
|
|
748
|
-
const _value = strictToNumber(value);
|
|
749
|
-
|
|
750
|
-
return Math.floor(Math.abs(_value)) & 1 ? true : false;
|
|
751
|
-
},
|
|
752
|
-
};
|
|
753
|
-
|
|
754
|
-
// -----------------------------------------------------------------------------
|
|
755
|
-
// LN
|
|
756
|
-
// -----------------------------------------------------------------------------
|
|
757
|
-
export const LN: FunctionDescription = {
|
|
758
|
-
description: _lt(`The logarithm of a number, base e (euler's number).`),
|
|
759
|
-
args: args(`
|
|
760
|
-
value (number) ${_lt("The value for which to calculate the logarithm, base e.")}
|
|
761
|
-
`),
|
|
762
|
-
returns: ["NUMBER"],
|
|
763
|
-
compute: function (value: any): number {
|
|
764
|
-
const _value = toNumber(value);
|
|
765
|
-
if (_value <= 0) {
|
|
766
|
-
throw new Error(
|
|
767
|
-
_lt(
|
|
768
|
-
"Function [[FUNCTION_NAME]] parameter 1 value is %s. It should be greater than 0.",
|
|
769
|
-
_value.toString()
|
|
770
|
-
)
|
|
771
|
-
);
|
|
772
|
-
}
|
|
773
|
-
return Math.log(_value);
|
|
774
|
-
},
|
|
775
|
-
};
|
|
776
|
-
|
|
777
|
-
// -----------------------------------------------------------------------------
|
|
778
|
-
// MOD
|
|
779
|
-
// -----------------------------------------------------------------------------
|
|
780
|
-
export const MOD: FunctionDescription = {
|
|
781
|
-
description: _lt(`Modulo (remainder) operator.`),
|
|
782
|
-
args: args(`
|
|
783
|
-
dividend (number) ${_lt("The number to be divided to find the remainder.")}
|
|
784
|
-
divisor (number) ${_lt("The number to divide by.")}
|
|
785
|
-
`),
|
|
786
|
-
returns: ["NUMBER"],
|
|
787
|
-
compute: function (dividend: any, divisor: any): number {
|
|
788
|
-
const _divisor = toNumber(divisor);
|
|
789
|
-
|
|
790
|
-
if (_divisor === 0) {
|
|
791
|
-
throw new Error(
|
|
792
|
-
_lt(
|
|
793
|
-
"Function MOD expects the parameter '%s' to be different from 0. Change '%s' to a value other than 0.",
|
|
794
|
-
MOD.args[1].name,
|
|
795
|
-
MOD.args[1].name
|
|
796
|
-
)
|
|
797
|
-
);
|
|
798
|
-
}
|
|
799
|
-
const _dividend = toNumber(dividend);
|
|
800
|
-
const modulus = _dividend % _divisor;
|
|
801
|
-
// -42 % 10 = -2 but we want 8, so need the code below
|
|
802
|
-
if ((modulus > 0 && _divisor < 0) || (modulus < 0 && _divisor > 0)) {
|
|
803
|
-
return modulus + _divisor;
|
|
804
|
-
}
|
|
805
|
-
return modulus;
|
|
806
|
-
},
|
|
807
|
-
};
|
|
808
|
-
|
|
809
|
-
// -----------------------------------------------------------------------------
|
|
810
|
-
// ODD
|
|
811
|
-
// -----------------------------------------------------------------------------
|
|
812
|
-
export const ODD: FunctionDescription = {
|
|
813
|
-
description: _lt(`Rounds a number up to the nearest odd integer.`),
|
|
814
|
-
args: args(`
|
|
815
|
-
value (number) ${_lt("The value to round to the next greatest odd number.")}
|
|
816
|
-
`),
|
|
817
|
-
returns: ["NUMBER"],
|
|
818
|
-
compute: function (value: any): number {
|
|
819
|
-
const _value = toNumber(value);
|
|
820
|
-
|
|
821
|
-
let temp = Math.ceil(Math.abs(_value));
|
|
822
|
-
temp = temp & 1 ? temp : temp + 1;
|
|
823
|
-
return _value < 0 ? -temp : temp;
|
|
824
|
-
},
|
|
825
|
-
};
|
|
826
|
-
|
|
827
|
-
// -----------------------------------------------------------------------------
|
|
828
|
-
// PI
|
|
829
|
-
// -----------------------------------------------------------------------------
|
|
830
|
-
export const PI: FunctionDescription = {
|
|
831
|
-
description: _lt(`The number pi.`),
|
|
832
|
-
args: [],
|
|
833
|
-
returns: ["NUMBER"],
|
|
834
|
-
compute: function (): number {
|
|
835
|
-
return Math.PI;
|
|
836
|
-
},
|
|
837
|
-
};
|
|
838
|
-
|
|
839
|
-
// -----------------------------------------------------------------------------
|
|
840
|
-
// POWER
|
|
841
|
-
// -----------------------------------------------------------------------------
|
|
842
|
-
export const POWER: FunctionDescription = {
|
|
843
|
-
description: _lt(`A number raised to a power.`),
|
|
844
|
-
args: args(`
|
|
845
|
-
base (number) ${_lt("The number to raise to the exponent power.")}
|
|
846
|
-
exponent (number) ${_lt("The exponent to raise base to.")}
|
|
847
|
-
`),
|
|
848
|
-
returns: ["NUMBER"],
|
|
849
|
-
compute: function (base: any, exponent: any): number {
|
|
850
|
-
const _base = toNumber(base);
|
|
851
|
-
const _exponent = toNumber(exponent);
|
|
852
|
-
|
|
853
|
-
if (_base >= 0) {
|
|
854
|
-
return Math.pow(_base, _exponent);
|
|
855
|
-
}
|
|
856
|
-
if (!Number.isInteger(_exponent)) {
|
|
857
|
-
throw new Error(
|
|
858
|
-
_lt(
|
|
859
|
-
"Function POWER expects the parameter '%s' to be an integer when parameter '%s' is negative. Change '%s' from [%s] to an integer value.",
|
|
860
|
-
POWER.args[1].name,
|
|
861
|
-
POWER.args[0].name,
|
|
862
|
-
POWER.args[1].name,
|
|
863
|
-
_exponent.toString()
|
|
864
|
-
)
|
|
865
|
-
);
|
|
866
|
-
}
|
|
867
|
-
return Math.pow(_base, _exponent);
|
|
868
|
-
},
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
// -----------------------------------------------------------------------------
|
|
872
|
-
// PRODUCT
|
|
873
|
-
// -----------------------------------------------------------------------------
|
|
874
|
-
export const PRODUCT: FunctionDescription = {
|
|
875
|
-
description: _lt("Result of multiplying a series of numbers together."),
|
|
876
|
-
args: args(`
|
|
877
|
-
factor1 (number, range<number>) ${_lt(
|
|
878
|
-
"The first number or range to calculate for the product."
|
|
879
|
-
)}
|
|
880
|
-
factor2 (number, range<number>, optional, repeating) ${_lt(
|
|
881
|
-
"More numbers or ranges to calculate for the product."
|
|
882
|
-
)}
|
|
883
|
-
`),
|
|
884
|
-
returns: ["NUMBER"],
|
|
885
|
-
compute: function (): number {
|
|
886
|
-
let count = 0;
|
|
887
|
-
let acc = 1;
|
|
888
|
-
for (let n of arguments) {
|
|
889
|
-
if (Array.isArray(n)) {
|
|
890
|
-
for (let i of n) {
|
|
891
|
-
for (let j of i) {
|
|
892
|
-
if (typeof j === "number") {
|
|
893
|
-
acc *= j;
|
|
894
|
-
count += 1;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
} else if (n !== null) {
|
|
899
|
-
acc *= strictToNumber(n);
|
|
900
|
-
count += 1;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
if (count === 0) {
|
|
904
|
-
return 0;
|
|
905
|
-
}
|
|
906
|
-
return acc;
|
|
907
|
-
},
|
|
908
|
-
};
|
|
909
|
-
|
|
910
|
-
// -----------------------------------------------------------------------------
|
|
911
|
-
// RAND
|
|
912
|
-
// -----------------------------------------------------------------------------
|
|
913
|
-
export const RAND: FunctionDescription = {
|
|
914
|
-
description: _lt("A random number between 0 inclusive and 1 exclusive."),
|
|
915
|
-
args: [],
|
|
916
|
-
returns: ["NUMBER"],
|
|
917
|
-
compute: function (): number {
|
|
918
|
-
return Math.random();
|
|
919
|
-
},
|
|
920
|
-
};
|
|
921
|
-
|
|
922
|
-
// -----------------------------------------------------------------------------
|
|
923
|
-
// RANDBETWEEN
|
|
924
|
-
// -----------------------------------------------------------------------------
|
|
925
|
-
export const RANDBETWEEN: FunctionDescription = {
|
|
926
|
-
description: _lt("Random integer between two values, inclusive."),
|
|
927
|
-
args: args(`
|
|
928
|
-
low (number) ${_lt("The low end of the random range.")}
|
|
929
|
-
high (number) ${_lt("The high end of the random range.")}
|
|
930
|
-
`),
|
|
931
|
-
returns: ["NUMBER"],
|
|
932
|
-
compute: function (low: any, high: any): number {
|
|
933
|
-
let _low = toNumber(low);
|
|
934
|
-
if (!Number.isInteger(_low)) {
|
|
935
|
-
_low = Math.ceil(_low);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
let _high = toNumber(high);
|
|
939
|
-
if (!Number.isInteger(_high)) {
|
|
940
|
-
_high = Math.floor(_high);
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
if (_high < _low) {
|
|
944
|
-
throw new Error(
|
|
945
|
-
_lt(
|
|
946
|
-
"Function RANDBETWEEN parameter '%s' value is %s. It should be greater than or equal to [%s].",
|
|
947
|
-
RANDBETWEEN.args[1].name,
|
|
948
|
-
_high.toString(),
|
|
949
|
-
_low.toString()
|
|
950
|
-
)
|
|
951
|
-
);
|
|
952
|
-
}
|
|
953
|
-
return _low + Math.ceil((_high - _low + 1) * Math.random()) - 1;
|
|
954
|
-
},
|
|
955
|
-
};
|
|
956
|
-
|
|
957
|
-
// -----------------------------------------------------------------------------
|
|
958
|
-
// ROUND
|
|
959
|
-
// -----------------------------------------------------------------------------
|
|
960
|
-
export const ROUND: FunctionDescription = {
|
|
961
|
-
description: _lt("Rounds a number according to standard rules."),
|
|
962
|
-
args: args(`
|
|
963
|
-
value (number) ${_lt("The value to round to places number of places.")}
|
|
964
|
-
places (number, optional, default=0) ${_lt("The number of decimal places to which to round.")}
|
|
965
|
-
`),
|
|
966
|
-
returns: ["NUMBER"],
|
|
967
|
-
compute: function (value: any, places: any = 0): number {
|
|
968
|
-
const _value = toNumber(value);
|
|
969
|
-
let _places = toNumber(places);
|
|
970
|
-
|
|
971
|
-
const absValue = Math.abs(_value);
|
|
972
|
-
let tempResult;
|
|
973
|
-
if (_places === 0) {
|
|
974
|
-
tempResult = Math.round(absValue);
|
|
975
|
-
} else {
|
|
976
|
-
if (!Number.isInteger(_places)) {
|
|
977
|
-
_places = Math.trunc(_places);
|
|
978
|
-
}
|
|
979
|
-
tempResult = Math.round(absValue * Math.pow(10, _places)) / Math.pow(10, _places);
|
|
980
|
-
}
|
|
981
|
-
return _value >= 0 ? tempResult : -tempResult;
|
|
982
|
-
},
|
|
983
|
-
};
|
|
984
|
-
|
|
985
|
-
// -----------------------------------------------------------------------------
|
|
986
|
-
// ROUNDDOWN
|
|
987
|
-
// -----------------------------------------------------------------------------
|
|
988
|
-
export const ROUNDDOWN: FunctionDescription = {
|
|
989
|
-
description: _lt(`Rounds down a number.`),
|
|
990
|
-
args: args(`
|
|
991
|
-
value (number) ${_lt("The value to round to places number of places, always rounding down.")}
|
|
992
|
-
places (number, optional, default=0) ${_lt("The number of decimal places to which to round.")}
|
|
993
|
-
`),
|
|
994
|
-
returns: ["NUMBER"],
|
|
995
|
-
compute: function (value: any, places: any = 0): number {
|
|
996
|
-
const _value = toNumber(value);
|
|
997
|
-
let _places = toNumber(places);
|
|
998
|
-
|
|
999
|
-
const absValue = Math.abs(_value);
|
|
1000
|
-
let tempResult;
|
|
1001
|
-
if (_places === 0) {
|
|
1002
|
-
tempResult = Math.floor(absValue);
|
|
1003
|
-
} else {
|
|
1004
|
-
if (!Number.isInteger(_places)) {
|
|
1005
|
-
_places = Math.trunc(_places);
|
|
1006
|
-
}
|
|
1007
|
-
tempResult = Math.floor(absValue * Math.pow(10, _places)) / Math.pow(10, _places);
|
|
1008
|
-
}
|
|
1009
|
-
return _value >= 0 ? tempResult : -tempResult;
|
|
1010
|
-
},
|
|
1011
|
-
};
|
|
1012
|
-
|
|
1013
|
-
// -----------------------------------------------------------------------------
|
|
1014
|
-
// ROUNDUP
|
|
1015
|
-
// -----------------------------------------------------------------------------
|
|
1016
|
-
export const ROUNDUP: FunctionDescription = {
|
|
1017
|
-
description: _lt(`Rounds up a number.`),
|
|
1018
|
-
args: args(`
|
|
1019
|
-
value (number) ${_lt("The value to round to places number of places, always rounding up.")}
|
|
1020
|
-
places (number, optional, default=0) ${_lt("The number of decimal places to which to round.")}
|
|
1021
|
-
`),
|
|
1022
|
-
returns: ["NUMBER"],
|
|
1023
|
-
compute: function (value: any, places: any): number {
|
|
1024
|
-
const _value = toNumber(value);
|
|
1025
|
-
let _places = toNumber(places);
|
|
1026
|
-
|
|
1027
|
-
const absValue = Math.abs(_value);
|
|
1028
|
-
let tempResult;
|
|
1029
|
-
if (_places === 0) {
|
|
1030
|
-
tempResult = Math.ceil(absValue);
|
|
1031
|
-
} else {
|
|
1032
|
-
if (!Number.isInteger(_places)) {
|
|
1033
|
-
_places = Math.trunc(_places);
|
|
1034
|
-
}
|
|
1035
|
-
tempResult = Math.ceil(absValue * Math.pow(10, _places)) / Math.pow(10, _places);
|
|
1036
|
-
}
|
|
1037
|
-
return _value >= 0 ? tempResult : -tempResult;
|
|
1038
|
-
},
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
|
-
// -----------------------------------------------------------------------------
|
|
1042
|
-
// SEC
|
|
1043
|
-
// -----------------------------------------------------------------------------
|
|
1044
|
-
export const SEC: FunctionDescription = {
|
|
1045
|
-
description: _lt("Secant of an angle provided in radians."),
|
|
1046
|
-
args: args(`
|
|
1047
|
-
angle (number) ${_lt("The angle to find the secant of, in radians.")}
|
|
1048
|
-
`),
|
|
1049
|
-
returns: ["NUMBER"],
|
|
1050
|
-
compute: function (angle: any): number {
|
|
1051
|
-
return 1 / Math.cos(toNumber(angle));
|
|
1052
|
-
},
|
|
1053
|
-
};
|
|
1054
|
-
|
|
1055
|
-
// -----------------------------------------------------------------------------
|
|
1056
|
-
// SECH
|
|
1057
|
-
// -----------------------------------------------------------------------------
|
|
1058
|
-
export const SECH: FunctionDescription = {
|
|
1059
|
-
description: _lt("Hyperbolic secant of any real number."),
|
|
1060
|
-
args: args(`
|
|
1061
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic secant of.")}
|
|
1062
|
-
`),
|
|
1063
|
-
returns: ["NUMBER"],
|
|
1064
|
-
compute: function (value: any): number {
|
|
1065
|
-
return 1 / Math.cosh(toNumber(value));
|
|
1066
|
-
},
|
|
1067
|
-
};
|
|
1068
|
-
|
|
1069
|
-
// -----------------------------------------------------------------------------
|
|
1070
|
-
// SIN
|
|
1071
|
-
// -----------------------------------------------------------------------------
|
|
1072
|
-
export const SIN: FunctionDescription = {
|
|
1073
|
-
description: _lt("Sine of an angle provided in radians."),
|
|
1074
|
-
args: args(`
|
|
1075
|
-
angle (number) ${_lt("The angle to find the sine of, in radians.")}
|
|
1076
|
-
`),
|
|
1077
|
-
returns: ["NUMBER"],
|
|
1078
|
-
compute: function (angle: number): number {
|
|
1079
|
-
return Math.sin(toNumber(angle));
|
|
1080
|
-
},
|
|
1081
|
-
};
|
|
1082
|
-
|
|
1083
|
-
// -----------------------------------------------------------------------------
|
|
1084
|
-
// SINH
|
|
1085
|
-
// -----------------------------------------------------------------------------
|
|
1086
|
-
export const SINH: FunctionDescription = {
|
|
1087
|
-
description: _lt("Hyperbolic sine of any real number."),
|
|
1088
|
-
args: args(`
|
|
1089
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic sine of.")}
|
|
1090
|
-
`),
|
|
1091
|
-
returns: ["NUMBER"],
|
|
1092
|
-
compute: function (value: any): number {
|
|
1093
|
-
return Math.sinh(toNumber(value));
|
|
1094
|
-
},
|
|
1095
|
-
};
|
|
1096
|
-
|
|
1097
|
-
// -----------------------------------------------------------------------------
|
|
1098
|
-
// SQRT
|
|
1099
|
-
// -----------------------------------------------------------------------------
|
|
1100
|
-
export const SQRT: FunctionDescription = {
|
|
1101
|
-
description: _lt("Positive square root of a positive number."),
|
|
1102
|
-
args: args(`
|
|
1103
|
-
value (number) ${_lt("The number for which to calculate the positive square root.")}
|
|
1104
|
-
`),
|
|
1105
|
-
returns: ["NUMBER"],
|
|
1106
|
-
compute: function (value: any): number {
|
|
1107
|
-
const _value = toNumber(value);
|
|
1108
|
-
|
|
1109
|
-
if (_value < 0) {
|
|
1110
|
-
throw new Error(
|
|
1111
|
-
_lt(
|
|
1112
|
-
"Function SQRT parameter '%s' value is negative. It should be positive or zero. Change '%s' from [%s] to a positive value.",
|
|
1113
|
-
SQRT.args[0].name,
|
|
1114
|
-
SQRT.args[0].name,
|
|
1115
|
-
_value.toString()
|
|
1116
|
-
)
|
|
1117
|
-
);
|
|
1118
|
-
}
|
|
1119
|
-
return Math.sqrt(_value);
|
|
1120
|
-
},
|
|
1121
|
-
};
|
|
1122
|
-
|
|
1123
|
-
// -----------------------------------------------------------------------------
|
|
1124
|
-
// SUM
|
|
1125
|
-
// -----------------------------------------------------------------------------
|
|
1126
|
-
export const SUM: FunctionDescription = {
|
|
1127
|
-
description: _lt("Sum of a series of numbers and/or cells."),
|
|
1128
|
-
args: args(`
|
|
1129
|
-
value1 (number, range<number>) ${_lt("The first number or range to add together.")}
|
|
1130
|
-
value2 (number, range<number>, optional, repeating) ${_lt(
|
|
1131
|
-
"Additional numbers or ranges to add to value1."
|
|
1132
|
-
)}
|
|
1133
|
-
`),
|
|
1134
|
-
returns: ["NUMBER"],
|
|
1135
|
-
compute: function (): number {
|
|
1136
|
-
return reduceNumbers(arguments, (acc, a) => acc + a, 0);
|
|
1137
|
-
},
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
// -----------------------------------------------------------------------------
|
|
1141
|
-
// SUMIF
|
|
1142
|
-
// -----------------------------------------------------------------------------
|
|
1143
|
-
export const SUMIF: FunctionDescription = {
|
|
1144
|
-
description: _lt("A conditional sum across a range."),
|
|
1145
|
-
args: args(`
|
|
1146
|
-
criteria_range (range) ${_lt("The range which is tested against criterion.")}
|
|
1147
|
-
criterion (string) ${_lt("The pattern or test to apply to range.")}
|
|
1148
|
-
sum_range (range, optional, default=criteria_range) ${_lt(
|
|
1149
|
-
"The range to be summed, if different from range."
|
|
1150
|
-
)}
|
|
1151
|
-
`),
|
|
1152
|
-
returns: ["NUMBER"],
|
|
1153
|
-
compute: function (criteria_range: any, criterion: any, sum_range: any = undefined): number {
|
|
1154
|
-
if (sum_range === undefined) {
|
|
1155
|
-
sum_range = criteria_range;
|
|
1156
|
-
}
|
|
1157
|
-
let sum = 0;
|
|
1158
|
-
visitMatchingRanges([criteria_range, criterion], (i, j) => {
|
|
1159
|
-
const value = sum_range[i][j];
|
|
1160
|
-
if (typeof value === "number") {
|
|
1161
|
-
sum += value;
|
|
1162
|
-
}
|
|
1163
|
-
});
|
|
1164
|
-
return sum;
|
|
1165
|
-
},
|
|
1166
|
-
};
|
|
1167
|
-
|
|
1168
|
-
// -----------------------------------------------------------------------------
|
|
1169
|
-
// SUMIFS
|
|
1170
|
-
// -----------------------------------------------------------------------------
|
|
1171
|
-
export const SUMIFS: FunctionDescription = {
|
|
1172
|
-
description: _lt("Sums a range depending on multiple criteria."),
|
|
1173
|
-
args: args(`
|
|
1174
|
-
sum_range (range) ${_lt("The range to sum.")}
|
|
1175
|
-
criteria_range1 (range) ${_lt("The range to check against criterion1.")}
|
|
1176
|
-
criterion1 (string) ${_lt("The pattern or test to apply to criteria_range1.")}
|
|
1177
|
-
additional_values (any, range, optional, repeating) ${_lt(
|
|
1178
|
-
"Additional criteria_range and criterion to check."
|
|
1179
|
-
)}
|
|
1180
|
-
`),
|
|
1181
|
-
// @compatibility: on google sheets, args definitions are next:
|
|
1182
|
-
// sum_range (any, range) The range to sum.
|
|
1183
|
-
// criteria_range1 (any, range) The range to check against criterion1.
|
|
1184
|
-
// criterion1 (string) The pattern or test to apply to criteria_range1.
|
|
1185
|
-
// criteria_range2 (any, range, optional, repeating) Additional ranges to check.
|
|
1186
|
-
// criterion2 (string, optional, repeating) Additional criteria to check.
|
|
1187
|
-
returns: ["NUMBER"],
|
|
1188
|
-
compute: function (sum_range, ...args): number {
|
|
1189
|
-
let sum = 0;
|
|
1190
|
-
visitMatchingRanges(args, (i, j) => {
|
|
1191
|
-
const value = sum_range[i][j];
|
|
1192
|
-
if (typeof value === "number") {
|
|
1193
|
-
sum += value;
|
|
1194
|
-
}
|
|
1195
|
-
});
|
|
1196
|
-
return sum;
|
|
1197
|
-
},
|
|
1198
|
-
};
|
|
1199
|
-
|
|
1200
|
-
// -----------------------------------------------------------------------------
|
|
1201
|
-
// TAN
|
|
1202
|
-
// -----------------------------------------------------------------------------
|
|
1203
|
-
export const TAN: FunctionDescription = {
|
|
1204
|
-
description: _lt("Tangent of an angle provided in radians."),
|
|
1205
|
-
args: args(`
|
|
1206
|
-
angle (number) ${_lt("The angle to find the tangent of, in radians.")}
|
|
1207
|
-
`),
|
|
1208
|
-
returns: ["NUMBER"],
|
|
1209
|
-
compute: function (angle: any): number {
|
|
1210
|
-
return Math.tan(toNumber(angle));
|
|
1211
|
-
},
|
|
1212
|
-
};
|
|
1213
|
-
|
|
1214
|
-
// -----------------------------------------------------------------------------
|
|
1215
|
-
// TANH
|
|
1216
|
-
// -----------------------------------------------------------------------------
|
|
1217
|
-
export const TANH: FunctionDescription = {
|
|
1218
|
-
description: _lt("Hyperbolic tangent of any real number."),
|
|
1219
|
-
args: args(`
|
|
1220
|
-
value (number) ${_lt("Any real value to calculate the hyperbolic tangent of.")}
|
|
1221
|
-
`),
|
|
1222
|
-
returns: ["NUMBER"],
|
|
1223
|
-
compute: function (value: any): number {
|
|
1224
|
-
return Math.tanh(toNumber(value));
|
|
1225
|
-
},
|
|
1226
|
-
};
|
|
1227
|
-
|
|
1228
|
-
// -----------------------------------------------------------------------------
|
|
1229
|
-
// TRUNC
|
|
1230
|
-
// -----------------------------------------------------------------------------
|
|
1231
|
-
export const TRUNC: FunctionDescription = {
|
|
1232
|
-
description: _lt("Truncates a number."),
|
|
1233
|
-
args: args(`
|
|
1234
|
-
value (number) ${_lt("The value to be truncated.")}
|
|
1235
|
-
places (number, optional, default=0) ${_lt(
|
|
1236
|
-
"The number of significant digits to the right of the decimal point to retain."
|
|
1237
|
-
)}
|
|
1238
|
-
`),
|
|
1239
|
-
returns: ["NUMBER"],
|
|
1240
|
-
compute: function (value: any, places: any = 0): number {
|
|
1241
|
-
const _value = toNumber(value);
|
|
1242
|
-
let _places = toNumber(places);
|
|
1243
|
-
|
|
1244
|
-
if (_places === 0) {
|
|
1245
|
-
return Math.trunc(_value);
|
|
1246
|
-
}
|
|
1247
|
-
if (!Number.isInteger(_places)) {
|
|
1248
|
-
_places = Math.trunc(_places);
|
|
1249
|
-
}
|
|
1250
|
-
return Math.trunc(_value * Math.pow(10, _places)) / Math.pow(10, _places);
|
|
1251
|
-
},
|
|
1252
|
-
};
|