@fable-org/fable-library-ts 1.0.0-beta-001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/Array.ts +1362 -0
  2. package/Async.ts +207 -0
  3. package/AsyncBuilder.ts +222 -0
  4. package/BigInt.ts +337 -0
  5. package/BitConverter.ts +165 -0
  6. package/Boolean.ts +22 -0
  7. package/CHANGELOG.md +15 -0
  8. package/Char.ts +222 -0
  9. package/Choice.ts +300 -0
  10. package/Date.ts +495 -0
  11. package/DateOffset.ts +324 -0
  12. package/DateOnly.ts +146 -0
  13. package/Decimal.ts +250 -0
  14. package/Double.ts +55 -0
  15. package/Encoding.ts +170 -0
  16. package/Event.ts +119 -0
  17. package/FSharp.Collections.ts +34 -0
  18. package/FSharp.Core.CompilerServices.ts +37 -0
  19. package/FSharp.Core.ts +86 -0
  20. package/Global.ts +37 -0
  21. package/Guid.ts +143 -0
  22. package/Int32.ts +156 -0
  23. package/List.ts +1417 -0
  24. package/Long.ts +49 -0
  25. package/MailboxProcessor.ts +125 -0
  26. package/Map.ts +1552 -0
  27. package/MapUtil.ts +120 -0
  28. package/MutableMap.ts +344 -0
  29. package/MutableSet.ts +248 -0
  30. package/Native.ts +11 -0
  31. package/Numeric.ts +80 -0
  32. package/Observable.ts +156 -0
  33. package/Option.ts +137 -0
  34. package/README.md +3 -0
  35. package/Random.ts +196 -0
  36. package/Range.ts +56 -0
  37. package/Reflection.ts +539 -0
  38. package/RegExp.ts +143 -0
  39. package/Result.ts +196 -0
  40. package/Seq.ts +1526 -0
  41. package/Seq2.ts +129 -0
  42. package/Set.ts +1955 -0
  43. package/String.ts +589 -0
  44. package/System.Collections.Generic.ts +380 -0
  45. package/System.Text.ts +137 -0
  46. package/SystemException.ts +7 -0
  47. package/TimeOnly.ts +131 -0
  48. package/TimeSpan.ts +194 -0
  49. package/Timer.ts +80 -0
  50. package/Types.ts +231 -0
  51. package/Unicode.13.0.0.ts +4 -0
  52. package/Uri.ts +206 -0
  53. package/Util.ts +928 -0
  54. package/lib/big.d.ts +338 -0
  55. package/lib/big.js +1054 -0
  56. package/package.json +24 -0
  57. package/tsconfig.json +103 -0
package/DateOffset.ts ADDED
@@ -0,0 +1,324 @@
1
+ /**
2
+ * DateTimeOffset functions.
3
+ *
4
+ * Note: DateOffset instances are always DateObjects in local
5
+ * timezone (because JS dates are all kinds of messed up).
6
+ * A local date returns UTC epoch when `.getTime()` is called.
7
+ *
8
+ * However, this means that in order to construct an UTC date
9
+ * from a DateOffset with offset of +5 hours, you first need
10
+ * to subtract those 5 hours, than add the "local" offset.
11
+ * As said, all kinds of messed up.
12
+ *
13
+ * Basically; invariant: date.getTime() always return UTC time.
14
+ */
15
+
16
+ import { int64, fromFloat64, toFloat64 } from "./BigInt.js";
17
+ import DateTime, { create as createDate, dateOffsetToString, daysInMonth, parseRaw, ticksToUnixEpochMilliseconds, unixEpochMillisecondsToTicks } from "./Date.js";
18
+ import { FSharpRef } from "./Types.js";
19
+ import { compareDates, DateKind, IDateTime, IDateTimeOffset, padWithZeros } from "./Util.js";
20
+
21
+ export default function DateTimeOffset(value: number, offset?: number) {
22
+ checkOffsetInRange(offset);
23
+ const d = new Date(value) as IDateTimeOffset;
24
+ d.offset = offset != null ? offset : new Date().getTimezoneOffset() * -60000;
25
+ return d;
26
+ }
27
+
28
+ export function offset(value: IDateTimeOffset): number {
29
+ return value.offset || 0;
30
+ }
31
+
32
+ function checkOffsetInRange(offset?: number) {
33
+ if (offset != null && offset !== 0) {
34
+ if (offset % 60000 !== 0) {
35
+ throw new Error("Offset must be specified in whole minutes.");
36
+ }
37
+ if (Math.abs(offset / 3600000) > 14) {
38
+ throw new Error("Offset must be within plus or minus 14 hours.");
39
+ }
40
+ }
41
+ }
42
+
43
+ export function fromDate(date: IDateTime, offset?: number) {
44
+ let offset2: number = 0;
45
+ switch (date.kind) {
46
+ case DateKind.UTC:
47
+ if(offset != null && offset !== 0) {
48
+ throw new Error("The UTC Offset for Utc DateTime instances must be 0.");
49
+ }
50
+ offset2 = 0;
51
+ break;
52
+
53
+ case DateKind.Local:
54
+ offset2 = date.getTimezoneOffset() * -60_000;
55
+ if(offset != null && offset !== offset2) {
56
+ throw new Error("The UTC Offset of the local dateTime parameter does not match the offset argument.");
57
+ }
58
+
59
+ break;
60
+
61
+ case DateKind.Unspecified:
62
+ default:
63
+ if(offset == null) {
64
+ offset2 = date.getTimezoneOffset() * -60_000;
65
+ }
66
+ else {
67
+ offset2 = offset;
68
+ }
69
+ break;
70
+ }
71
+
72
+ return DateTimeOffset(date.getTime(), offset2);
73
+ }
74
+
75
+ export function fromTicks(ticks: int64, offset: number) {
76
+ const ms = ticksToUnixEpochMilliseconds(ticks) - offset;
77
+ return DateTimeOffset(ms, offset);
78
+ }
79
+
80
+ export function fromUnixTimeMilliseconds(ms: int64) {
81
+ return DateTimeOffset(toFloat64(ms), 0)
82
+ }
83
+
84
+ export function fromUnixTimeSeconds(seconds: int64) {
85
+ return DateTimeOffset(toFloat64(seconds * 1000n), 0)
86
+ }
87
+
88
+ export function getUtcTicks(date: IDateTimeOffset) {
89
+ return unixEpochMillisecondsToTicks(date.getTime(), 0);
90
+ }
91
+
92
+ export function minValue() {
93
+ // This is "0001-01-01T00:00:00.000Z", actual JS min value is -8640000000000000
94
+ return DateTimeOffset(-62135596800000, 0);
95
+ }
96
+
97
+ export function maxValue() {
98
+ // This is "9999-12-31T23:59:59.999Z", actual JS max value is 8640000000000000
99
+ return DateTimeOffset(253402300799999, 0);
100
+ }
101
+
102
+ export function parse(str: string): IDateTimeOffset {
103
+ const [date, offsetMatch] = parseRaw(str);
104
+ const offset = offsetMatch == null
105
+ ? date.getTimezoneOffset() * -60000
106
+ : (offsetMatch === "Z" ? 0 : offsetMatch * 60000);
107
+ return DateTimeOffset(date.getTime(), offset);
108
+ }
109
+
110
+ export function tryParse(v: string, defValue: FSharpRef<IDateTimeOffset>): boolean {
111
+ try {
112
+ defValue.contents = parse(v);
113
+ return true;
114
+ } catch (_err) {
115
+ return false;
116
+ }
117
+ }
118
+
119
+ export function create(
120
+ year: number, month: number, day: number,
121
+ h: number, m: number, s: number,
122
+ ms: number, offset?: number) {
123
+ if (offset == null) {
124
+ offset = ms;
125
+ ms = 0;
126
+ }
127
+ checkOffsetInRange(offset);
128
+ let date: Date;
129
+ if (offset === 0) {
130
+ date = new Date(Date.UTC(year, month - 1, day, h, m, s, ms));
131
+ if (year <= 99) {
132
+ date.setUTCFullYear(year, month - 1, day);
133
+ }
134
+ } else {
135
+ const str =
136
+ padWithZeros(year, 4) + "-" +
137
+ padWithZeros(month, 2) + "-" +
138
+ padWithZeros(day, 2) + "T" +
139
+ padWithZeros(h, 2) + ":" +
140
+ padWithZeros(m, 2) + ":" +
141
+ padWithZeros(s, 2) + "." +
142
+ padWithZeros(ms, 3) +
143
+ dateOffsetToString(offset);
144
+ date = new Date(str);
145
+ }
146
+ const dateValue = date.getTime();
147
+ if (isNaN(dateValue)) {
148
+ throw new Error("The parameters describe an unrepresentable Date");
149
+ }
150
+ return DateTimeOffset(dateValue, offset);
151
+ }
152
+
153
+ export function now() {
154
+ const date = new Date();
155
+ const offset = date.getTimezoneOffset() * -60000;
156
+ return DateTimeOffset(date.getTime(), offset);
157
+ }
158
+
159
+ export function utcNow() {
160
+ const date = now();
161
+ return DateTimeOffset(date.getTime(), 0);
162
+ }
163
+
164
+ export function toUniversalTime(date: IDateTimeOffset): Date {
165
+ return DateTime(date.getTime(), DateKind.UTC);
166
+ }
167
+
168
+ export function toLocalTime(date: IDateTimeOffset): Date {
169
+ return DateTime(date.getTime(), DateKind.Local);
170
+ }
171
+
172
+ export function timeOfDay(d: IDateTimeOffset) {
173
+ const d2 = new Date(d.getTime() + (d.offset ?? 0));
174
+ return d2.getUTCHours() * 3600000
175
+ + d2.getUTCMinutes() * 60000
176
+ + d2.getUTCSeconds() * 1000
177
+ + d2.getUTCMilliseconds();
178
+ }
179
+
180
+ export function date(d: IDateTimeOffset) {
181
+ const d2 = new Date(d.getTime() + (d.offset ?? 0));
182
+ return createDate(d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate(), 0, 0, 0, 0);
183
+ }
184
+
185
+ export function day(d: IDateTimeOffset) {
186
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCDate();
187
+ }
188
+
189
+ export function hour(d: IDateTimeOffset) {
190
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCHours();
191
+ }
192
+
193
+ export function millisecond(d: IDateTimeOffset) {
194
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCMilliseconds();
195
+ }
196
+
197
+ export function minute(d: IDateTimeOffset) {
198
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCMinutes();
199
+ }
200
+
201
+ export function month(d: IDateTimeOffset) {
202
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCMonth() + 1;
203
+ }
204
+
205
+ export function second(d: IDateTimeOffset) {
206
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCSeconds();
207
+ }
208
+
209
+ export function year(d: IDateTimeOffset) {
210
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCFullYear();
211
+ }
212
+
213
+ export function dayOfWeek(d: IDateTimeOffset) {
214
+ return new Date(d.getTime() + (d.offset ?? 0)).getUTCDay();
215
+ }
216
+
217
+ export function dayOfYear(d: IDateTimeOffset) {
218
+ const d2 = new Date(d.getTime() + (d.offset ?? 0));
219
+ const _year = d2.getUTCFullYear();
220
+ const _month = d2.getUTCMonth() + 1;
221
+ let _day = d2.getUTCDate();
222
+ for (let i = 1; i < _month; i++) {
223
+ _day += daysInMonth(_year, i);
224
+ }
225
+ return _day;
226
+ }
227
+
228
+ export function add(d: IDateTimeOffset, ts: number) {
229
+ return DateTimeOffset(d.getTime() + ts, (d.offset ?? 0));
230
+ }
231
+
232
+ export function addDays(d: IDateTimeOffset, v: number) {
233
+ return add(d, v * 86400000);
234
+ }
235
+
236
+ export function addHours(d: IDateTimeOffset, v: number) {
237
+ return add(d, v * 3600000);
238
+ }
239
+
240
+ export function addMinutes(d: IDateTimeOffset, v: number) {
241
+ return add(d, v * 60000);
242
+ }
243
+
244
+ export function addSeconds(d: IDateTimeOffset, v: number) {
245
+ return add(d, v * 1000);
246
+ }
247
+
248
+ export function addMilliseconds(d: IDateTimeOffset, v: number) {
249
+ return add(d, v);
250
+ }
251
+
252
+ export function addTicks(d: IDateTimeOffset, v: int64) {
253
+ return add(d, toFloat64(v / 10000n));
254
+ }
255
+
256
+ export function addYears(d: IDateTimeOffset, v: number) {
257
+ const newMonth = d.getUTCMonth() + 1;
258
+ const newYear = d.getUTCFullYear() + v;
259
+ const _daysInMonth = daysInMonth(newYear, newMonth);
260
+ const newDay = Math.min(_daysInMonth, d.getUTCDate());
261
+ return create(newYear, newMonth, newDay, d.getUTCHours(), d.getUTCMinutes(),
262
+ d.getUTCSeconds(), d.getUTCMilliseconds(), (d.offset ?? 0));
263
+ }
264
+
265
+ export function addMonths(d: IDateTimeOffset, v: number) {
266
+ const d2 = new Date(d.getTime() + (d.offset ?? 0));
267
+ let newMonth = d2.getUTCMonth() + 1 + v;
268
+ let newMonth_ = 0;
269
+ let yearOffset = 0;
270
+ if (newMonth > 12) {
271
+ newMonth_ = newMonth % 12;
272
+ yearOffset = Math.floor(newMonth / 12);
273
+ newMonth = newMonth_;
274
+ } else if (newMonth < 1) {
275
+ newMonth_ = 12 + newMonth % 12;
276
+ yearOffset = Math.floor(newMonth / 12) + (newMonth_ === 12 ? -1 : 0);
277
+ newMonth = newMonth_;
278
+ }
279
+ const newYear = d2.getUTCFullYear() + yearOffset;
280
+ const _daysInMonth = daysInMonth(newYear, newMonth);
281
+ const newDay = Math.min(_daysInMonth, d2.getUTCDate());
282
+ return create(newYear, newMonth, newDay, d2.getUTCHours(), d2.getUTCMinutes(),
283
+ d2.getUTCSeconds(), d2.getUTCMilliseconds(), (d.offset ?? 0));
284
+ }
285
+
286
+ export function subtract<Input extends number | IDateTimeOffset, Output = Input extends number ? IDateTimeOffset : number>(d: IDateTimeOffset, that: Input): Output {
287
+ return typeof that === "number"
288
+ ? DateTimeOffset(d.getTime() - that, (d.offset ?? 0)) as Output
289
+ : d.getTime() - that.getTime() as Output;
290
+ }
291
+
292
+ export function equals(d1: IDateTimeOffset, d2: IDateTimeOffset) {
293
+ return d1.getTime() === d2.getTime();
294
+ }
295
+
296
+ export function equalsExact(d1: IDateTimeOffset, d2: IDateTimeOffset) {
297
+ return d1.getTime() === d2.getTime() && d1.offset === d2.offset;
298
+ }
299
+
300
+ export function compare(d1: IDateTimeOffset, d2: IDateTimeOffset) {
301
+ return compareDates(d1, d2);
302
+ }
303
+
304
+ export const compareTo = compare;
305
+
306
+ export function op_Addition(x: IDateTimeOffset, y: number) {
307
+ return add(x, y);
308
+ }
309
+
310
+ export function op_Subtraction<Input extends number | IDateTimeOffset, Output = Input extends number ? IDateTimeOffset : number>(x: IDateTimeOffset, y: Input): Output {
311
+ return subtract(x, y);
312
+ }
313
+
314
+ export function toOffset(d: IDateTimeOffset, offset: number): IDateTimeOffset {
315
+ return DateTimeOffset(d.getTime(), offset);
316
+ }
317
+
318
+ export function toUnixTimeMilliseconds(d: IDateTimeOffset): int64 {
319
+ return fromFloat64(d.getTime());
320
+ }
321
+
322
+ export function toUnixTimeSeconds(d: IDateTimeOffset): int64 {
323
+ return fromFloat64(d.getTime() / 1000.0);
324
+ }
package/DateOnly.ts ADDED
@@ -0,0 +1,146 @@
1
+ import { FSharpRef } from "./Types.js";
2
+ import { DateTime, getTicks, dayOfYear as Date_dayOfYear, year as Date_year, month as Date_month, day as Date_day, daysInMonth as Date_daysInMonth, ticksToUnixEpochMilliseconds } from "./Date.js";
3
+ import { IDateTime, DateKind, padWithZeros } from "./Util.js";
4
+
5
+ export function fromUnixMilliseconds(value: number) {
6
+ return DateTime(value, DateKind.UTC);
7
+ }
8
+
9
+ export function create(year: number, month: number, day: number) {
10
+ const d = fromUnixMilliseconds(Date.UTC(year, month - 1, day));
11
+ if (year <= 99) {
12
+ d.setUTCFullYear(year);
13
+ }
14
+ return d;
15
+ }
16
+
17
+ export function maxValue() {
18
+ // This is "9999-12-31T00:00:00.000Z"
19
+ return fromUnixMilliseconds(253402214400000);
20
+ }
21
+
22
+ export function minValue() {
23
+ // This is "0001-01-01T00:00:00.000Z"
24
+ return fromUnixMilliseconds(-62135596800000);
25
+ }
26
+
27
+ export function dayNumber(d: IDateTime) {
28
+ return Number((getTicks(d) / 864000000000n));
29
+ }
30
+
31
+ export function fromDayNumber(dayNumber: number) {
32
+ const ticks = 864000000000n * BigInt(dayNumber);
33
+ return fromUnixMilliseconds(ticksToUnixEpochMilliseconds(ticks));
34
+ }
35
+
36
+ export function fromDateTime(d: IDateTime) {
37
+ return create(Date_year(d), Date_month(d), Date_day(d));
38
+ }
39
+
40
+ export function day(d: IDateTime) {
41
+ return d.getUTCDate();
42
+ }
43
+
44
+ export function month(d: IDateTime) {
45
+ return d.getUTCMonth() + 1;
46
+ }
47
+
48
+ export function year(d: IDateTime) {
49
+ return d.getUTCFullYear();
50
+ }
51
+
52
+ export function dayOfWeek(d: IDateTime) {
53
+ return d.getUTCDay();
54
+ }
55
+
56
+ export function dayOfYear(d: IDateTime) {
57
+ return Date_dayOfYear(d);
58
+ }
59
+
60
+ export function toDateTime(d: IDateTime, time: number, kind = DateKind.Unspecified) {
61
+ return DateTime(d.getTime() + time + (kind !== DateKind.UTC ? d.getTimezoneOffset() : 0) * 60000, kind);
62
+ }
63
+
64
+ export function toString(d: IDateTime, format = "d", _provider?: any) {
65
+ if (["d", "o", "O"].indexOf(format) === -1) {
66
+ throw new Error("Custom formats are not supported");
67
+ }
68
+
69
+ const y = padWithZeros(year(d), 4);
70
+ const m = padWithZeros(month(d), 2);
71
+ const dd = padWithZeros(day(d), 2);
72
+
73
+ return format === "d" ? `${m}/${dd}/${y}` : `${y}-${m}-${dd}`;
74
+ }
75
+
76
+ export function parse(str: string) {
77
+ function fail(): IDateTime {
78
+ throw new Error(`String '${str}' was not recognized as a valid DateOnly.`);
79
+ }
80
+
81
+ // Allowed separators: . , / -
82
+ // TODO whitespace alone as the separator
83
+ //
84
+ // Whitespace around separators
85
+ //
86
+ // Allowed format types:
87
+ // yyyy/mm/dd
88
+ // mm/dd/yyyy
89
+ // mm/dd
90
+ // mm/yyyy
91
+ // yyyy/mm
92
+ const r = /^\s*(\d{1,4})(?:\s*[.,-\/]\s*(\d{1,2}))?\s*[.,-\/]\s*(\d{1,4})\s*$/.exec(str);
93
+ if (r != null) {
94
+ let y = 0;
95
+ let m = 0;
96
+ let d = 1;
97
+
98
+ if (r[2] == null) {
99
+ if (r[1].length < 3) {
100
+ if (r[3].length < 3) {
101
+ // 12/30 = December 30, {CurrentYear}
102
+ y = new Date().getFullYear();
103
+ m = +r[1];
104
+ d = +r[3];
105
+ } else {
106
+ // 12/2000 = December 1, 2000
107
+ m = +r[1];
108
+ y = +r[3];
109
+ }
110
+ } else {
111
+ if (r[3].length > 2)
112
+ fail();
113
+
114
+ // 2000/12 = December 1, 2000
115
+ y = +r[1];
116
+ m = +r[3];
117
+ }
118
+ } else {
119
+ // 2000/1/30 or 1/30/2000
120
+ const yearFirst = r[1].length > 2;
121
+ const yTmp = r[yearFirst ? 1 : 3];
122
+ y = +yTmp;
123
+
124
+ // year 0-29 is 2000-2029, 30-99 is 1930-1999
125
+ if (yTmp.length < 3)
126
+ y += y >= 30 ? 1900 : 2000;
127
+
128
+ m = +r[yearFirst ? 2 : 1];
129
+ d = +r[yearFirst ? 3 : 2];
130
+ }
131
+
132
+ if (y > 0 && m > 0 && m < 13 && d > 0 && d <= Date_daysInMonth(y, m))
133
+ return create(y, m, d);
134
+ }
135
+
136
+ return fail();
137
+ }
138
+
139
+ export function tryParse(v: string, defValue: FSharpRef<IDateTime>): boolean {
140
+ try {
141
+ defValue.contents = parse(v);
142
+ return true;
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
package/Decimal.ts ADDED
@@ -0,0 +1,250 @@
1
+ import Decimal, { BigSource } from "./lib/big.js";
2
+ import { Numeric, symbol } from "./Numeric.js";
3
+ import { FSharpRef } from "./Types.js";
4
+ import { combineHashCodes } from "./Util.js";
5
+
6
+ Decimal.prototype.GetHashCode = function () {
7
+ return combineHashCodes([this.s, this.e].concat(this.c))
8
+ }
9
+
10
+ Decimal.prototype.Equals = function (x: Decimal) {
11
+ return !this.cmp(x)
12
+ }
13
+
14
+ Decimal.prototype.CompareTo = function (x: Decimal) {
15
+ return this.cmp(x)
16
+ }
17
+
18
+ Decimal.prototype[symbol] = function() {
19
+ const _this = this;
20
+ return {
21
+ multiply: (y: Numeric) => _this.mul(y as BigSource),
22
+ toPrecision: (sd?: number) => _this.toPrecision(sd),
23
+ toExponential: (dp?: number) => _this.toExponential(dp),
24
+ toFixed: (dp?: number) => _this.toFixed(dp),
25
+ toHex: () => (Number(_this) >>> 0).toString(16),
26
+ }
27
+ }
28
+
29
+ export default Decimal;
30
+ export type decimal = Decimal;
31
+
32
+ export const get_Zero = new Decimal(0);
33
+ export const get_One = new Decimal(1);
34
+ export const get_MinusOne = new Decimal(-1);
35
+ export const get_MaxValue = new Decimal("79228162514264337593543950335");
36
+ export const get_MinValue = new Decimal("-79228162514264337593543950335");
37
+
38
+ export function compare(x: Decimal, y: Decimal) {
39
+ return x.cmp(y);
40
+ }
41
+
42
+ export function equals(x: Decimal, y: Decimal) {
43
+ return !x.cmp(y);
44
+ }
45
+
46
+ export function abs(x: Decimal) { return x.abs(); }
47
+ export function sign(x: Decimal): number { return x < get_Zero ? -1 : x > get_Zero ? 1 : 0; }
48
+
49
+ export function max(x: Decimal, y: Decimal): Decimal { return x > y ? x : y; }
50
+ export function min(x: Decimal, y: Decimal): Decimal { return x < y ? x : y; }
51
+
52
+ export function maxMagnitude(x: Decimal, y: Decimal): Decimal { return abs(x) > abs(y) ? x : y; }
53
+ export function minMagnitude(x: Decimal, y: Decimal): Decimal { return abs(x) < abs(y) ? x : y; }
54
+
55
+ export function clamp(x: Decimal, min: Decimal, max: Decimal): Decimal {
56
+ return x < min ? min : x > max ? max : x;
57
+ }
58
+
59
+ export function round(x: Decimal, digits: number = 0) {
60
+ return x.round(digits, 2 /* ROUND_HALF_EVEN */);
61
+ }
62
+
63
+ export function truncate(x: Decimal) {
64
+ return x.round(0, 0 /* ROUND_DOWN */);
65
+ }
66
+
67
+ export function ceiling(x: Decimal) {
68
+ return x.round(0, x.cmp(0) >= 0 ? 3 /* ROUND_UP */ : 0 /* ROUND_DOWN */);
69
+ }
70
+
71
+ export function floor(x: Decimal) {
72
+ return x.round(0, x.cmp(0) >= 0 ? 0 /* ROUND_DOWN */ : 3 /* ROUND_UP */);
73
+ }
74
+
75
+ export function pow(x: Decimal, n: number) {
76
+ return x.pow(n);
77
+ }
78
+
79
+ export function sqrt(x: Decimal) {
80
+ return x.sqrt();
81
+ }
82
+
83
+ export function op_Addition(x: Decimal, y: Decimal) {
84
+ return x.add(y);
85
+ }
86
+
87
+ export function op_Subtraction(x: Decimal, y: Decimal) {
88
+ return x.sub(y);
89
+ }
90
+
91
+ export function op_Multiply(x: Decimal, y: Decimal) {
92
+ return x.mul(y);
93
+ }
94
+
95
+ export function op_Division(x: Decimal, y: Decimal) {
96
+ return x.div(y);
97
+ }
98
+
99
+ export function op_Modulus(x: Decimal, y: Decimal) {
100
+ return x.mod(y);
101
+ }
102
+
103
+ export function op_UnaryNegation(x: Decimal) {
104
+ const x2 = new Decimal(x);
105
+ x2.s = -x2.s || 0;
106
+ return x2;
107
+ }
108
+
109
+ export function op_UnaryPlus(x: Decimal) {
110
+ return x;
111
+ }
112
+
113
+ export const add = op_Addition;
114
+ export const subtract = op_Subtraction;
115
+ export const multiply = op_Multiply;
116
+ export const divide = op_Division;
117
+ export const remainder = op_Modulus;
118
+ export const negate = op_UnaryNegation;
119
+
120
+ export function toString(x: Decimal) {
121
+ return x.toString();
122
+ }
123
+
124
+ export function tryParse(str: string, defValue: FSharpRef<Decimal>): boolean {
125
+ try {
126
+ defValue.contents = new Decimal(str.trim());
127
+ return true;
128
+ } catch {
129
+ return false;
130
+ }
131
+ }
132
+
133
+ export function parse(str: string): Decimal {
134
+ const defValue = new FSharpRef(get_Zero);
135
+ if (tryParse(str, defValue)) {
136
+ return defValue.contents;
137
+ } else {
138
+ throw new Error(`The input string ${str} was not in a correct format.`);
139
+ }
140
+ }
141
+
142
+ export function toNumber(x: Decimal) {
143
+ return +x;
144
+ }
145
+
146
+ function decimalToHex(dec: Uint8Array, bitSize: number) {
147
+ const hex = new Uint8Array(bitSize / 4 | 0);
148
+ let hexCount = 1;
149
+ for (let d = 0; d < dec.length; d++) {
150
+ let value = dec[d];
151
+ for (let i = 0; i < hexCount; i++) {
152
+ const digit = hex[i] * 10 + value | 0;
153
+ hex[i] = digit & 0xF;
154
+ value = digit >> 4;
155
+ }
156
+ if (value !== 0) {
157
+ hex[hexCount++] = value;
158
+ }
159
+ }
160
+ return hex.slice(0, hexCount); // digits in reverse order
161
+ }
162
+
163
+ function hexToDecimal(hex: Uint8Array, bitSize: number) {
164
+ const dec = new Uint8Array(bitSize * 301 / 1000 + 1 | 0);
165
+ let decCount = 1;
166
+ for (let d = hex.length - 1; d >= 0; d--) {
167
+ let carry = hex[d];
168
+ for (let i = 0; i < decCount; i++) {
169
+ const val = dec[i] * 16 + carry | 0;
170
+ dec[i] = (val % 10) | 0;
171
+ carry = (val / 10) | 0;
172
+ }
173
+ while (carry > 0) {
174
+ dec[decCount++] = (carry % 10) | 0;
175
+ carry = (carry / 10) | 0;
176
+ }
177
+ }
178
+ return dec.slice(0, decCount); // digits in reverse order
179
+ }
180
+
181
+ function setInt32Bits(hexDigits: Uint8Array, bits: number, offset: number) {
182
+ for (let i = 0; i < 8; i++) {
183
+ hexDigits[offset + i] = (bits >> (i * 4)) & 0xF;
184
+ }
185
+ }
186
+
187
+ function getInt32Bits(hexDigits: Uint8Array, offset: number) {
188
+ let bits = 0;
189
+ for (let i = 0; i < 8; i++) {
190
+ bits = bits | (hexDigits[offset + i] << (i * 4));
191
+ }
192
+ return bits;
193
+ }
194
+
195
+ export function fromIntArray(bits: ArrayLike<number>) {
196
+ return fromInts(bits[0], bits[1], bits[2], bits[3]);
197
+ }
198
+
199
+ export function fromInts(low: number, mid: number, high: number, signExp: number) {
200
+ const isNegative = signExp < 0;
201
+ const scale = (signExp >> 16) & 0x7F;
202
+ return fromParts(low, mid, high, isNegative, scale);
203
+ }
204
+
205
+ export function fromParts(low: number, mid: number, high: number, isNegative: boolean, scale: number) {
206
+ const bitSize = 96;
207
+ const hexDigits = new Uint8Array(bitSize / 4);
208
+ setInt32Bits(hexDigits, low, 0);
209
+ setInt32Bits(hexDigits, mid, 8);
210
+ setInt32Bits(hexDigits, high, 16);
211
+ const decDigits = hexToDecimal(hexDigits, bitSize);
212
+ scale = scale & 0x7F;
213
+ const big = new Decimal(0);
214
+ big.c = Array.from(decDigits.reverse());
215
+ big.e = decDigits.length - scale - 1;
216
+ big.s = isNegative ? -1 : 1;
217
+ const d = new Decimal(big);
218
+ return d;
219
+ }
220
+
221
+ export function getBits(d: Decimal) {
222
+ const bitSize = 96;
223
+ const decDigits = Uint8Array.from(d.c);
224
+ const hexDigits = decimalToHex(decDigits, bitSize);
225
+ const low = getInt32Bits(hexDigits, 0);
226
+ const mid = getInt32Bits(hexDigits, 8);
227
+ const high = getInt32Bits(hexDigits, 16);
228
+ const decStr = d.toString();
229
+ const dotPos = decStr.indexOf(".");
230
+ const scale = dotPos < 0 ? 0 : decStr.length - dotPos - 1;
231
+ const signExp = ((scale & 0x7F) << 16) | (d.s < 0 ? 0x80000000 : 0);
232
+ return [low, mid, high, signExp];
233
+ }
234
+
235
+ // export function makeRangeStepFunction(step: Decimal, last: Decimal) {
236
+ // const stepComparedWithZero = step.cmp(get_Zero);
237
+ // if (stepComparedWithZero === 0) {
238
+ // throw new Error("The step of a range cannot be zero");
239
+ // }
240
+ // const stepGreaterThanZero = stepComparedWithZero > 0;
241
+ // return (x: Decimal) => {
242
+ // const comparedWithLast = x.cmp(last);
243
+ // if ((stepGreaterThanZero && comparedWithLast <= 0)
244
+ // || (!stepGreaterThanZero && comparedWithLast >= 0)) {
245
+ // return [x, op_Addition(x, step)];
246
+ // } else {
247
+ // return undefined;
248
+ // }
249
+ // };
250
+ // }