create-mendix-widget-gleam 2.0.13 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/package.json +5 -1
- package/src/index.mjs +22 -7
- package/src/templates/readme_md.mjs +6 -6
- package/template/docs/glendix_guide.md +204 -1
- package/template/gleam.toml +1 -1
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_inline +0 -0
- package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_meta +0 -0
- package/tui/build/dev/javascript/etch/etch/command.mjs +479 -0
- package/tui/build/dev/javascript/etch/etch/cursor.mjs +164 -0
- package/tui/build/dev/javascript/etch/etch/event.mjs +2399 -0
- package/tui/build/dev/javascript/etch/etch/internal/consts.mjs +3 -0
- package/tui/build/dev/javascript/etch/etch/stdout.mjs +375 -0
- package/tui/build/dev/javascript/etch/etch/style.mjs +741 -0
- package/tui/build/dev/javascript/etch/etch/terminal.mjs +137 -0
- package/tui/build/dev/javascript/etch/gleam.mjs +1 -0
- package/tui/build/dev/javascript/etch/input/event_ffi.erl +73 -0
- package/tui/build/dev/javascript/etch/input/input_ffi.mjs +192 -0
- package/tui/build/dev/javascript/etch/input/signal_handler.erl +33 -0
- package/tui/build/dev/javascript/etch/terminal/terminal_ffi.erl +22 -0
- package/tui/build/dev/javascript/etch/terminal/terminal_ffi.mjs +37 -0
- package/tui/build/dev/javascript/etch/terminal/tty_state.erl +29 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/application.mjs +38 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/atom.mjs +2 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/charlist.mjs +1 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/node.mjs +12 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/port.mjs +1 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/process.mjs +161 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/reference.mjs +1 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam.mjs +1 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@application.erl +43 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@atom.erl +94 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@charlist.erl +42 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@node.erl +80 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@port.erl +8 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@process.erl +868 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@reference.erl +21 -0
- package/tui/build/dev/javascript/gleam_erlang/gleam_erlang_ffi.erl +164 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/array.mjs +24 -0
- package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/promise.mjs +105 -0
- package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/symbol.mjs +7 -0
- package/tui/build/dev/javascript/gleam_javascript/gleam.mjs +1 -0
- package/tui/build/dev/javascript/gleam_javascript/gleam_javascript_ffi.mjs +133 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_inline +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta +0 -0
- package/tui/build/dev/javascript/gleam_stdlib/dict.mjs +710 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/bit_array.mjs +286 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/bool.mjs +295 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/bytes_tree.mjs +225 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/dict.mjs +455 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic/decode.mjs +993 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic.mjs +35 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/float.mjs +528 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/function.mjs +6 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/int.mjs +764 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/io.mjs +8 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/list.mjs +3063 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/option.mjs +386 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/order.mjs +166 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/pair.mjs +96 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/result.mjs +448 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/set.mjs +413 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/string.mjs +695 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/string_tree.mjs +128 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam/uri.mjs +1151 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam.mjs +1 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@bit_array.erl +347 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@bool.erl +334 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@bytes_tree.erl +211 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@dict.erl +513 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic.erl +105 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic@decode.erl +1114 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@float.erl +711 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@function.erl +18 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@int.erl +972 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@io.erl +76 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@list.erl +2735 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@option.erl +381 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@order.erl +188 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@pair.erl +104 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@result.erl +500 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@set.erl +430 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@string.erl +964 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@string_tree.erl +202 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam@uri.erl +1042 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.erl +534 -0
- package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.mjs +1133 -0
- package/tui/build/dev/javascript/gleam_version +1 -0
- package/tui/build/dev/javascript/prelude.mjs +1575 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_inline +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_meta +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_warnings +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_inline +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_meta +0 -0
- package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_warnings +0 -0
- package/tui/build/dev/javascript/tui/gleam.mjs +1 -0
- package/tui/build/dev/javascript/tui/tui/prompt.mjs +521 -0
- package/tui/build/dev/javascript/tui/tui.mjs +334 -0
- package/tui/build/dev/javascript/tui/tui_ffi.mjs +32 -0
|
@@ -0,0 +1,1133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BitArray,
|
|
3
|
+
List$Empty,
|
|
4
|
+
List$NonEmpty,
|
|
5
|
+
List$isEmpty,
|
|
6
|
+
List$isNonEmpty,
|
|
7
|
+
Result$Ok,
|
|
8
|
+
Result$Error,
|
|
9
|
+
Result$isOk,
|
|
10
|
+
Result$isError,
|
|
11
|
+
UtfCodepoint,
|
|
12
|
+
stringBits,
|
|
13
|
+
toBitArray,
|
|
14
|
+
bitArraySlice,
|
|
15
|
+
CustomType,
|
|
16
|
+
} from "./gleam.mjs";
|
|
17
|
+
import { Some, None } from "./gleam/option.mjs";
|
|
18
|
+
import {
|
|
19
|
+
default as Dict,
|
|
20
|
+
fold as dict_fold,
|
|
21
|
+
get as dict_get,
|
|
22
|
+
from as dict_from_iterable,
|
|
23
|
+
} from "./dict.mjs";
|
|
24
|
+
import { classify } from "./gleam/dynamic.mjs";
|
|
25
|
+
import { DecodeError$DecodeError } from "./gleam/dynamic/decode.mjs";
|
|
26
|
+
|
|
27
|
+
const Nil = undefined;
|
|
28
|
+
|
|
29
|
+
export function identity(x) {
|
|
30
|
+
return x;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function parse_int(value) {
|
|
34
|
+
if (/^[-+]?(\d+)$/.test(value)) {
|
|
35
|
+
return Result$Ok(parseInt(value));
|
|
36
|
+
} else {
|
|
37
|
+
return Result$Error(Nil);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function parse_float(value) {
|
|
42
|
+
if (/^[-+]?(\d+)\.(\d+)([eE][-+]?\d+)?$/.test(value)) {
|
|
43
|
+
return Result$Ok(parseFloat(value));
|
|
44
|
+
} else {
|
|
45
|
+
return Result$Error(Nil);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function to_string(term) {
|
|
50
|
+
return term.toString();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function int_to_base_string(int, base) {
|
|
54
|
+
return int.toString(base).toUpperCase();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const int_base_patterns = {
|
|
58
|
+
2: /[^0-1]/,
|
|
59
|
+
3: /[^0-2]/,
|
|
60
|
+
4: /[^0-3]/,
|
|
61
|
+
5: /[^0-4]/,
|
|
62
|
+
6: /[^0-5]/,
|
|
63
|
+
7: /[^0-6]/,
|
|
64
|
+
8: /[^0-7]/,
|
|
65
|
+
9: /[^0-8]/,
|
|
66
|
+
10: /[^0-9]/,
|
|
67
|
+
11: /[^0-9a]/,
|
|
68
|
+
12: /[^0-9a-b]/,
|
|
69
|
+
13: /[^0-9a-c]/,
|
|
70
|
+
14: /[^0-9a-d]/,
|
|
71
|
+
15: /[^0-9a-e]/,
|
|
72
|
+
16: /[^0-9a-f]/,
|
|
73
|
+
17: /[^0-9a-g]/,
|
|
74
|
+
18: /[^0-9a-h]/,
|
|
75
|
+
19: /[^0-9a-i]/,
|
|
76
|
+
20: /[^0-9a-j]/,
|
|
77
|
+
21: /[^0-9a-k]/,
|
|
78
|
+
22: /[^0-9a-l]/,
|
|
79
|
+
23: /[^0-9a-m]/,
|
|
80
|
+
24: /[^0-9a-n]/,
|
|
81
|
+
25: /[^0-9a-o]/,
|
|
82
|
+
26: /[^0-9a-p]/,
|
|
83
|
+
27: /[^0-9a-q]/,
|
|
84
|
+
28: /[^0-9a-r]/,
|
|
85
|
+
29: /[^0-9a-s]/,
|
|
86
|
+
30: /[^0-9a-t]/,
|
|
87
|
+
31: /[^0-9a-u]/,
|
|
88
|
+
32: /[^0-9a-v]/,
|
|
89
|
+
33: /[^0-9a-w]/,
|
|
90
|
+
34: /[^0-9a-x]/,
|
|
91
|
+
35: /[^0-9a-y]/,
|
|
92
|
+
36: /[^0-9a-z]/,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export function int_from_base_string(string, base) {
|
|
96
|
+
if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) {
|
|
97
|
+
return Result$Error(Nil);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const result = parseInt(string, base);
|
|
101
|
+
|
|
102
|
+
if (isNaN(result)) {
|
|
103
|
+
return Result$Error(Nil);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Result$Ok(result);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function string_replace(string, target, substitute) {
|
|
110
|
+
return string.replaceAll(target, substitute);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function string_reverse(string) {
|
|
114
|
+
return [...string].reverse().join("");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function string_length(string) {
|
|
118
|
+
if (string === "") {
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
const iterator = graphemes_iterator(string);
|
|
122
|
+
if (iterator) {
|
|
123
|
+
let i = 0;
|
|
124
|
+
for (const _ of iterator) {
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
return i;
|
|
128
|
+
} else {
|
|
129
|
+
return string.match(/./gsu).length;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function graphemes(string) {
|
|
134
|
+
const iterator = graphemes_iterator(string);
|
|
135
|
+
if (iterator) {
|
|
136
|
+
return arrayToList(Array.from(iterator).map((item) => item.segment));
|
|
137
|
+
} else {
|
|
138
|
+
return arrayToList(string.match(/./gsu));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let segmenter = undefined;
|
|
143
|
+
|
|
144
|
+
function graphemes_iterator(string) {
|
|
145
|
+
if (globalThis.Intl && Intl.Segmenter) {
|
|
146
|
+
segmenter ||= new Intl.Segmenter();
|
|
147
|
+
return segmenter.segment(string)[Symbol.iterator]();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function pop_grapheme(string) {
|
|
152
|
+
let first;
|
|
153
|
+
const iterator = graphemes_iterator(string);
|
|
154
|
+
if (iterator) {
|
|
155
|
+
first = iterator.next().value?.segment;
|
|
156
|
+
} else {
|
|
157
|
+
first = string.match(/./su)?.[0];
|
|
158
|
+
}
|
|
159
|
+
if (first) {
|
|
160
|
+
return Result$Ok([first, string.slice(first.length)]);
|
|
161
|
+
} else {
|
|
162
|
+
return Result$Error(Nil);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function pop_codeunit(str) {
|
|
167
|
+
return [str.charCodeAt(0) | 0, str.slice(1)];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function lowercase(string) {
|
|
171
|
+
return string.toLowerCase();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function uppercase(string) {
|
|
175
|
+
return string.toUpperCase();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function less_than(a, b) {
|
|
179
|
+
return a < b;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function add(a, b) {
|
|
183
|
+
return a + b;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function split(xs, pattern) {
|
|
187
|
+
return arrayToList(xs.split(pattern));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function concat(xs) {
|
|
191
|
+
let result = "";
|
|
192
|
+
for (const x of xs) {
|
|
193
|
+
result = result + x;
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function length(data) {
|
|
199
|
+
return data.length;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function string_byte_slice(string, index, length) {
|
|
203
|
+
return string.slice(index, index + length);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function string_grapheme_slice(string, idx, len) {
|
|
207
|
+
if (len <= 0 || idx >= string.length) {
|
|
208
|
+
return "";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const iterator = graphemes_iterator(string);
|
|
212
|
+
if (iterator) {
|
|
213
|
+
while (idx-- > 0) {
|
|
214
|
+
iterator.next();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let result = "";
|
|
218
|
+
|
|
219
|
+
while (len-- > 0) {
|
|
220
|
+
const v = iterator.next().value;
|
|
221
|
+
if (v === undefined) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
result += v.segment;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return result;
|
|
229
|
+
} else {
|
|
230
|
+
return string
|
|
231
|
+
.match(/./gsu)
|
|
232
|
+
.slice(idx, idx + len)
|
|
233
|
+
.join("");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function string_codeunit_slice(str, from, length) {
|
|
238
|
+
return str.slice(from, from + length);
|
|
239
|
+
}
|
|
240
|
+
export function crop_string(string, substring) {
|
|
241
|
+
return string.substring(string.indexOf(substring));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function contains_string(haystack, needle) {
|
|
245
|
+
return haystack.indexOf(needle) >= 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function starts_with(haystack, needle) {
|
|
249
|
+
return haystack.startsWith(needle);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function ends_with(haystack, needle) {
|
|
253
|
+
return haystack.endsWith(needle);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function split_once(haystack, needle) {
|
|
257
|
+
const index = haystack.indexOf(needle);
|
|
258
|
+
if (index >= 0) {
|
|
259
|
+
const before = haystack.slice(0, index);
|
|
260
|
+
const after = haystack.slice(index + needle.length);
|
|
261
|
+
return Result$Ok([before, after]);
|
|
262
|
+
} else {
|
|
263
|
+
return Result$Error(Nil);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const unicode_whitespaces = [
|
|
268
|
+
"\u0020", // Space
|
|
269
|
+
"\u0009", // Horizontal tab
|
|
270
|
+
"\u000A", // Line feed
|
|
271
|
+
"\u000B", // Vertical tab
|
|
272
|
+
"\u000C", // Form feed
|
|
273
|
+
"\u000D", // Carriage return
|
|
274
|
+
"\u0085", // Next line
|
|
275
|
+
"\u2028", // Line separator
|
|
276
|
+
"\u2029", // Paragraph separator
|
|
277
|
+
].join("");
|
|
278
|
+
|
|
279
|
+
const trim_start_regex = /* @__PURE__ */ new RegExp(
|
|
280
|
+
`^[${unicode_whitespaces}]*`,
|
|
281
|
+
);
|
|
282
|
+
const trim_end_regex = /* @__PURE__ */ new RegExp(`[${unicode_whitespaces}]*$`);
|
|
283
|
+
|
|
284
|
+
export function trim_start(string) {
|
|
285
|
+
return string.replace(trim_start_regex, "");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function trim_end(string) {
|
|
289
|
+
return string.replace(trim_end_regex, "");
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function bit_array_from_string(string) {
|
|
293
|
+
return toBitArray([stringBits(string)]);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function bit_array_bit_size(bit_array) {
|
|
297
|
+
return bit_array.bitSize;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function bit_array_byte_size(bit_array) {
|
|
301
|
+
return bit_array.byteSize;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function bit_array_pad_to_bytes(bit_array) {
|
|
305
|
+
const trailingBitsCount = bit_array.bitSize % 8;
|
|
306
|
+
|
|
307
|
+
// If the bit array is a whole number of bytes it can be returned unchanged
|
|
308
|
+
if (trailingBitsCount === 0) {
|
|
309
|
+
return bit_array;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const finalByte = bit_array.byteAt(bit_array.byteSize - 1);
|
|
313
|
+
|
|
314
|
+
// The required final byte has its unused trailing bits set to zero
|
|
315
|
+
const unusedBitsCount = 8 - trailingBitsCount;
|
|
316
|
+
const correctFinalByte = (finalByte >> unusedBitsCount) << unusedBitsCount;
|
|
317
|
+
|
|
318
|
+
// If the unused bits in the final byte are already set to zero then the
|
|
319
|
+
// existing buffer can be re-used, avoiding a copy
|
|
320
|
+
if (finalByte === correctFinalByte) {
|
|
321
|
+
return new BitArray(
|
|
322
|
+
bit_array.rawBuffer,
|
|
323
|
+
bit_array.byteSize * 8,
|
|
324
|
+
bit_array.bitOffset,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Copy the bit array into a new aligned buffer and set the correct final byte
|
|
329
|
+
const buffer = new Uint8Array(bit_array.byteSize);
|
|
330
|
+
for (let i = 0; i < buffer.length - 1; i++) {
|
|
331
|
+
buffer[i] = bit_array.byteAt(i);
|
|
332
|
+
}
|
|
333
|
+
buffer[buffer.length - 1] = correctFinalByte;
|
|
334
|
+
|
|
335
|
+
return new BitArray(buffer);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export function bit_array_concat(bit_arrays) {
|
|
339
|
+
return toBitArray(bit_arrays.toArray());
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function console_log(term) {
|
|
343
|
+
console.log(term);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function console_error(term) {
|
|
347
|
+
console.error(term);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function crash(message) {
|
|
351
|
+
throw new globalThis.Error(message);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export function bit_array_to_string(bit_array) {
|
|
355
|
+
// If the bit array isn't a whole number of bytes then return an error
|
|
356
|
+
if (bit_array.bitSize % 8 !== 0) {
|
|
357
|
+
return Result$Error(Nil);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
try {
|
|
361
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
362
|
+
|
|
363
|
+
if (bit_array.bitOffset === 0) {
|
|
364
|
+
return Result$Ok(decoder.decode(bit_array.rawBuffer));
|
|
365
|
+
} else {
|
|
366
|
+
// The input data isn't aligned, so copy it into a new aligned buffer so
|
|
367
|
+
// that TextDecoder can be used
|
|
368
|
+
const buffer = new Uint8Array(bit_array.byteSize);
|
|
369
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
370
|
+
buffer[i] = bit_array.byteAt(i);
|
|
371
|
+
}
|
|
372
|
+
return Result$Ok(decoder.decode(buffer));
|
|
373
|
+
}
|
|
374
|
+
} catch {
|
|
375
|
+
return Result$Error(Nil);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export function print(string) {
|
|
380
|
+
if (typeof process === "object" && process.stdout?.write) {
|
|
381
|
+
process.stdout.write(string); // We can write without a trailing newline
|
|
382
|
+
} else if (typeof Deno === "object") {
|
|
383
|
+
Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline
|
|
384
|
+
} else {
|
|
385
|
+
console.log(string); // We're in a browser. Newlines are mandated
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function print_error(string) {
|
|
390
|
+
if (typeof process === "object" && process.stderr?.write) {
|
|
391
|
+
process.stderr.write(string); // We can write without a trailing newline
|
|
392
|
+
} else if (typeof Deno === "object") {
|
|
393
|
+
Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline
|
|
394
|
+
} else {
|
|
395
|
+
console.error(string); // We're in a browser. Newlines are mandated
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export function print_debug(string) {
|
|
400
|
+
if (typeof process === "object" && process.stderr?.write) {
|
|
401
|
+
process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr`
|
|
402
|
+
} else if (typeof Deno === "object") {
|
|
403
|
+
Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr`
|
|
404
|
+
} else {
|
|
405
|
+
console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function ceiling(float) {
|
|
410
|
+
return Math.ceil(float);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function floor(float) {
|
|
414
|
+
return Math.floor(float);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export function round(float) {
|
|
418
|
+
return Math.round(float);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
export function truncate(float) {
|
|
422
|
+
return Math.trunc(float);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export function power(base, exponent) {
|
|
426
|
+
// It is checked in Gleam that:
|
|
427
|
+
// - The base is non-negative and that the exponent is not fractional.
|
|
428
|
+
// - The base is non-zero and the exponent is non-negative (otherwise
|
|
429
|
+
// the result will essentially be division by zero).
|
|
430
|
+
// It can thus be assumed that valid input is passed to the Math.pow
|
|
431
|
+
// function and a NaN or Infinity value will not be produced.
|
|
432
|
+
return Math.pow(base, exponent);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function random_uniform() {
|
|
436
|
+
const random_uniform_result = Math.random();
|
|
437
|
+
// With round-to-nearest-even behavior, the ranges claimed for the functions below
|
|
438
|
+
// (excluding the one for Math.random() itself) aren't exact.
|
|
439
|
+
// If extremely large bounds are chosen (2^53 or higher),
|
|
440
|
+
// it's possible in extremely rare cases to calculate the usually-excluded upper bound.
|
|
441
|
+
// Note that as numbers in JavaScript are IEEE 754 floating point numbers
|
|
442
|
+
// See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random>
|
|
443
|
+
// Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0:
|
|
444
|
+
if (random_uniform_result === 1.0) {
|
|
445
|
+
return random_uniform();
|
|
446
|
+
}
|
|
447
|
+
return random_uniform_result;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export function bit_array_slice(bits, position, length) {
|
|
451
|
+
const start = Math.min(position, position + length);
|
|
452
|
+
const end = Math.max(position, position + length);
|
|
453
|
+
|
|
454
|
+
if (start < 0 || end * 8 > bits.bitSize) {
|
|
455
|
+
return Result$Error(Nil);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return Result$Ok(bitArraySlice(bits, start * 8, end * 8));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export function codepoint(int) {
|
|
462
|
+
return new UtfCodepoint(int);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export function string_to_codepoint_integer_list(string) {
|
|
466
|
+
return arrayToList(Array.from(string).map((item) => item.codePointAt(0)));
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export function utf_codepoint_list_to_string(utf_codepoint_integer_list) {
|
|
470
|
+
return utf_codepoint_integer_list
|
|
471
|
+
.toArray()
|
|
472
|
+
.map((x) => String.fromCodePoint(x.value))
|
|
473
|
+
.join("");
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export function utf_codepoint_to_int(utf_codepoint) {
|
|
477
|
+
return utf_codepoint.value;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function unsafe_percent_decode(string) {
|
|
481
|
+
return decodeURIComponent(string || "");
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function unsafe_percent_decode_query(string) {
|
|
485
|
+
return decodeURIComponent((string || "").replace("+", " "));
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
export function percent_decode(string) {
|
|
489
|
+
try {
|
|
490
|
+
return Result$Ok(unsafe_percent_decode(string));
|
|
491
|
+
} catch {
|
|
492
|
+
return Result$Error(Nil);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export function percent_encode(string) {
|
|
497
|
+
return encodeURIComponent(string).replace("%2B", "+");
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export function parse_query(query) {
|
|
501
|
+
try {
|
|
502
|
+
const pairs = [];
|
|
503
|
+
for (const section of query.split("&")) {
|
|
504
|
+
const [key, value] = section.split("=");
|
|
505
|
+
if (!key) continue;
|
|
506
|
+
|
|
507
|
+
const decodedKey = unsafe_percent_decode_query(key);
|
|
508
|
+
const decodedValue = unsafe_percent_decode_query(value);
|
|
509
|
+
pairs.push([decodedKey, decodedValue]);
|
|
510
|
+
}
|
|
511
|
+
return Result$Ok(arrayToList(pairs));
|
|
512
|
+
} catch {
|
|
513
|
+
return Result$Error(Nil);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const b64EncodeLookup = [
|
|
518
|
+
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
|
|
519
|
+
84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
|
|
520
|
+
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
|
|
521
|
+
122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47,
|
|
522
|
+
];
|
|
523
|
+
|
|
524
|
+
let b64TextDecoder;
|
|
525
|
+
|
|
526
|
+
// Implementation based on https://github.com/mitschabaude/fast-base64/blob/main/js.js
|
|
527
|
+
export function base64_encode(bit_array, padding) {
|
|
528
|
+
b64TextDecoder ??= new TextDecoder();
|
|
529
|
+
|
|
530
|
+
bit_array = bit_array_pad_to_bytes(bit_array);
|
|
531
|
+
|
|
532
|
+
const m = bit_array.byteSize;
|
|
533
|
+
const k = m % 3;
|
|
534
|
+
const n = Math.floor(m / 3) * 4 + (k && k + 1);
|
|
535
|
+
const N = Math.ceil(m / 3) * 4;
|
|
536
|
+
const encoded = new Uint8Array(N);
|
|
537
|
+
|
|
538
|
+
for (let i = 0, j = 0; j < m; i += 4, j += 3) {
|
|
539
|
+
const y =
|
|
540
|
+
(bit_array.byteAt(j) << 16) +
|
|
541
|
+
(bit_array.byteAt(j + 1) << 8) +
|
|
542
|
+
(bit_array.byteAt(j + 2) | 0);
|
|
543
|
+
|
|
544
|
+
encoded[i] = b64EncodeLookup[y >> 18];
|
|
545
|
+
encoded[i + 1] = b64EncodeLookup[(y >> 12) & 0x3f];
|
|
546
|
+
encoded[i + 2] = b64EncodeLookup[(y >> 6) & 0x3f];
|
|
547
|
+
encoded[i + 3] = b64EncodeLookup[y & 0x3f];
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
let base64 = b64TextDecoder.decode(new Uint8Array(encoded.buffer, 0, n));
|
|
551
|
+
|
|
552
|
+
if (padding) {
|
|
553
|
+
if (k === 1) {
|
|
554
|
+
base64 += "==";
|
|
555
|
+
} else if (k === 2) {
|
|
556
|
+
base64 += "=";
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return base64;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64
|
|
564
|
+
export function base64_decode(sBase64) {
|
|
565
|
+
try {
|
|
566
|
+
const binString = atob(sBase64);
|
|
567
|
+
const length = binString.length;
|
|
568
|
+
const array = new Uint8Array(length);
|
|
569
|
+
for (let i = 0; i < length; i++) {
|
|
570
|
+
array[i] = binString.charCodeAt(i);
|
|
571
|
+
}
|
|
572
|
+
return Result$Ok(new BitArray(array));
|
|
573
|
+
} catch {
|
|
574
|
+
return Result$Error(Nil);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export function classify_dynamic(data) {
|
|
579
|
+
if (typeof data === "string") {
|
|
580
|
+
return "String";
|
|
581
|
+
} else if (typeof data === "boolean") {
|
|
582
|
+
return "Bool";
|
|
583
|
+
} else if (isResult(data)) {
|
|
584
|
+
return "Result";
|
|
585
|
+
} else if (isList(data)) {
|
|
586
|
+
return "List";
|
|
587
|
+
} else if (data instanceof BitArray) {
|
|
588
|
+
return "BitArray";
|
|
589
|
+
} else if (data instanceof Dict) {
|
|
590
|
+
return "Dict";
|
|
591
|
+
} else if (Number.isInteger(data)) {
|
|
592
|
+
return "Int";
|
|
593
|
+
} else if (Array.isArray(data)) {
|
|
594
|
+
return `Array`;
|
|
595
|
+
} else if (typeof data === "number") {
|
|
596
|
+
return "Float";
|
|
597
|
+
} else if (data === null) {
|
|
598
|
+
return "Nil";
|
|
599
|
+
} else if (data === undefined) {
|
|
600
|
+
return "Nil";
|
|
601
|
+
} else {
|
|
602
|
+
const type = typeof data;
|
|
603
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
export function byte_size(string) {
|
|
608
|
+
return new TextEncoder().encode(string).length;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// In JavaScript, bitwise operations convert numbers to a sequence of 32 bits,
|
|
612
|
+
// while Erlang uses arbitrary precision integers.
|
|
613
|
+
//
|
|
614
|
+
// To get around this, every function here follows this pattern:
|
|
615
|
+
//
|
|
616
|
+
// 1. If both values fit in the 32-bit signed integer range, use the standard
|
|
617
|
+
// JavaScript bitwise operators directly.
|
|
618
|
+
//
|
|
619
|
+
// Note: For bitwise_shift_left, the result also needs to fit in 32 bits,
|
|
620
|
+
// so we use floating-point multiplication instead.
|
|
621
|
+
//
|
|
622
|
+
// 2. If either value falls outside the safe integer range (-2^53, 2^53),
|
|
623
|
+
// fall back to BigInt arithmetic, then downcast the result back to a Number.
|
|
624
|
+
//
|
|
625
|
+
// 3. Otherwise (safe integers outside the 32-bit range), we split the operation
|
|
626
|
+
// across the high 21 bits and low 32 bits individually:
|
|
627
|
+
//
|
|
628
|
+
// x1 $ x2 = ((hi(x1) $ hi(x2)) << 32) | (lo(x1) $ lo(x2))
|
|
629
|
+
//
|
|
630
|
+
// where `$` is a bitwise operator.
|
|
631
|
+
//
|
|
632
|
+
// We split both values into a `hi` and a `lo` part:
|
|
633
|
+
//
|
|
634
|
+
// hi(x) = Math.floor(x / 2^32) the upper 21 bits
|
|
635
|
+
// lo(x) = x >>> 0 the lower 32 bits (as unsigned)
|
|
636
|
+
//
|
|
637
|
+
// For `hi`, we use that shifts are equal to multiplication/division with
|
|
638
|
+
// powers of two to get around the 32-bit range limitation. Math.floor is
|
|
639
|
+
// used instead of truncation since arithmetic right shift fills with the
|
|
640
|
+
// sign bit. For negative numbers, the discarded bits were non-zero
|
|
641
|
+
// (representing a positive fractional part), so discarding them makes the
|
|
642
|
+
// result strictly more negative, i.e. rounding away from 0.
|
|
643
|
+
//
|
|
644
|
+
// This works because bitwise operators are distributive across bit ranges:
|
|
645
|
+
//
|
|
646
|
+
// x1 $ x2 = (hi(x1) $ hi(x2)) << 32 | (lo(x1) $ lo(x2))
|
|
647
|
+
// = (hi(x1) $ hi(x2)) * 2^32 + (lo(x1) $ lo(x2))
|
|
648
|
+
//
|
|
649
|
+
// JavaScript bitwise operators truncate inputs to signed 32-bit integers,
|
|
650
|
+
// so `x1 $ x2` already computes `lo(x1) $ lo(x2)` — we just need to
|
|
651
|
+
// reinterpret the signed result as unsigned using `>>> 0`:
|
|
652
|
+
//
|
|
653
|
+
// lo(x1) $ lo(x2) = (x1 $ x2) >>> 0 = lo(x1 $ x2)
|
|
654
|
+
// => x1 $ x2 = (hi(x1) $ hi(x2)) * 2^32 + lo(x1 $ x2).
|
|
655
|
+
//
|
|
656
|
+
const MIN_I32 = -(2 ** 31); // -2147483648
|
|
657
|
+
const MAX_I32 = 2 ** 31 - 1; // 2147483647
|
|
658
|
+
const U32 = 2 ** 32;
|
|
659
|
+
const MAX_SAFE = Number.MAX_SAFE_INTEGER;
|
|
660
|
+
const MIN_SAFE = Number.MIN_SAFE_INTEGER;
|
|
661
|
+
|
|
662
|
+
export function bitwise_and(x, y) {
|
|
663
|
+
if (x >= MIN_I32 && x <= MAX_I32 && y >= MIN_I32 && y <= MAX_I32) return x & y;
|
|
664
|
+
if (x < MIN_SAFE || x > MAX_SAFE || y < MIN_SAFE || y > MAX_SAFE)
|
|
665
|
+
return Number(BigInt(x) & BigInt(y));
|
|
666
|
+
|
|
667
|
+
return (Math.floor(x / U32) & Math.floor(y / U32)) * U32 + ((x & y) >>> 0);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export function bitwise_or(x, y) {
|
|
671
|
+
if (x >= MIN_I32 && x <= MAX_I32 && y >= MIN_I32 && y <= MAX_I32) return x | y;
|
|
672
|
+
if (x < MIN_SAFE || x > MAX_SAFE || y < MIN_SAFE || y > MAX_SAFE)
|
|
673
|
+
return Number(BigInt(x) | BigInt(y));
|
|
674
|
+
|
|
675
|
+
return (Math.floor(x / U32) | Math.floor(y / U32)) * U32 + ((x | y) >>> 0);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export function bitwise_exclusive_or(x, y) {
|
|
679
|
+
if (x >= MIN_I32 && x <= MAX_I32 && y >= MIN_I32 && y <= MAX_I32) return x ^ y;
|
|
680
|
+
if (x < MIN_SAFE || x > MAX_SAFE || y < MIN_SAFE || y > MAX_SAFE)
|
|
681
|
+
return Number(BigInt(x) ^ BigInt(y));
|
|
682
|
+
|
|
683
|
+
return (Math.floor(x / U32) ^ Math.floor(y / U32)) * U32 + ((x ^ y) >>> 0);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export function bitwise_not(x) {
|
|
687
|
+
if (x >= MIN_I32 && x <= MAX_I32) return ~x;
|
|
688
|
+
if (x < MIN_SAFE || x > MAX_SAFE) return Number(~BigInt(x));
|
|
689
|
+
|
|
690
|
+
return ~Math.floor(x / U32) * U32 + (~x >>> 0);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
export function bitwise_shift_right(x, y) {
|
|
694
|
+
if (y === 0) return x;
|
|
695
|
+
if (y < 0) return bitwise_shift_left(x, -y);
|
|
696
|
+
if (y < 32 && x >= MIN_I32 && x <= MAX_I32) return x >> y;
|
|
697
|
+
if (x < MIN_SAFE || x > MAX_SAFE) return Number(BigInt(x) >> BigInt(y));
|
|
698
|
+
|
|
699
|
+
const ahi = Math.floor(x / U32);
|
|
700
|
+
|
|
701
|
+
// Shifting right by y < 32 moves bits across the hi/lo boundary:
|
|
702
|
+
//
|
|
703
|
+
// before: [ hi (21 bits) | lo (32 bits) ]
|
|
704
|
+
// after: [ hi >> y | (hi's low y bits) ++ (lo >> y) ]
|
|
705
|
+
//
|
|
706
|
+
// The new low word has two sources:
|
|
707
|
+
// - lo's bits shifted down: x >>> y (>>> treats x as unsigned 32-bit)
|
|
708
|
+
// - hi's bottom y bits shifted up: ahi << (32 - y).
|
|
709
|
+
if (y < 32) return (ahi >> y) * U32 + (((x >>> y) | (ahi << (32 - y))) >>> 0);
|
|
710
|
+
|
|
711
|
+
// Shifting by >= 32 wipes out the entire low word. The result is just the
|
|
712
|
+
// high word shifted right by the remaining amount.
|
|
713
|
+
return ahi >> (y - 32);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
export function bitwise_shift_left(x, y) {
|
|
717
|
+
if (y === 0) return x;
|
|
718
|
+
if (y < 0) return bitwise_shift_right(x, -y);
|
|
719
|
+
if (y < 31) return x * (1 << y);
|
|
720
|
+
return x * 2 ** y;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
export function inspect(v) {
|
|
724
|
+
return new Inspector().inspect(v);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
export function float_to_string(float) {
|
|
728
|
+
const string = float.toString().replace("+", "");
|
|
729
|
+
if (string.indexOf(".") >= 0) {
|
|
730
|
+
return string;
|
|
731
|
+
} else {
|
|
732
|
+
const index = string.indexOf("e");
|
|
733
|
+
if (index >= 0) {
|
|
734
|
+
return string.slice(0, index) + ".0" + string.slice(index);
|
|
735
|
+
} else {
|
|
736
|
+
return string + ".0";
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
class Inspector {
|
|
742
|
+
#references = new Set();
|
|
743
|
+
|
|
744
|
+
inspect(v) {
|
|
745
|
+
const t = typeof v;
|
|
746
|
+
if (v === true) return "True";
|
|
747
|
+
if (v === false) return "False";
|
|
748
|
+
if (v === null) return "//js(null)";
|
|
749
|
+
if (v === undefined) return "Nil";
|
|
750
|
+
if (t === "string") return this.#string(v);
|
|
751
|
+
if (t === "bigint" || Number.isInteger(v)) return v.toString();
|
|
752
|
+
if (t === "number") return float_to_string(v);
|
|
753
|
+
if (v instanceof UtfCodepoint) return this.#utfCodepoint(v);
|
|
754
|
+
if (v instanceof BitArray) return this.#bit_array(v);
|
|
755
|
+
if (v instanceof RegExp) return `//js(${v})`;
|
|
756
|
+
if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`;
|
|
757
|
+
if (v instanceof globalThis.Error) return `//js(${v.toString()})`;
|
|
758
|
+
if (v instanceof Function) {
|
|
759
|
+
const args = [];
|
|
760
|
+
for (const i of Array(v.length).keys())
|
|
761
|
+
args.push(String.fromCharCode(i + 97));
|
|
762
|
+
return `//fn(${args.join(", ")}) { ... }`;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (this.#references.size === this.#references.add(v).size) {
|
|
766
|
+
return "//js(circular reference)";
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
let printed;
|
|
770
|
+
if (Array.isArray(v)) {
|
|
771
|
+
printed = `#(${v.map((v) => this.inspect(v)).join(", ")})`;
|
|
772
|
+
} else if (isList(v)) {
|
|
773
|
+
printed = this.#list(v);
|
|
774
|
+
} else if (v instanceof CustomType) {
|
|
775
|
+
printed = this.#customType(v);
|
|
776
|
+
} else if (v instanceof Dict) {
|
|
777
|
+
printed = this.#dict(v);
|
|
778
|
+
} else if (v instanceof Set) {
|
|
779
|
+
return `//js(Set(${[...v].map((v) => this.inspect(v)).join(", ")}))`;
|
|
780
|
+
} else {
|
|
781
|
+
printed = this.#object(v);
|
|
782
|
+
}
|
|
783
|
+
this.#references.delete(v);
|
|
784
|
+
return printed;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
#object(v) {
|
|
788
|
+
const name = Object.getPrototypeOf(v)?.constructor?.name || "Object";
|
|
789
|
+
const props = [];
|
|
790
|
+
for (const k of Object.keys(v)) {
|
|
791
|
+
props.push(`${this.inspect(k)}: ${this.inspect(v[k])}`);
|
|
792
|
+
}
|
|
793
|
+
const body = props.length ? " " + props.join(", ") + " " : "";
|
|
794
|
+
const head = name === "Object" ? "" : name + " ";
|
|
795
|
+
return `//js(${head}{${body}})`;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
#dict(map) {
|
|
799
|
+
let body = "dict.from_list([";
|
|
800
|
+
let first = true;
|
|
801
|
+
|
|
802
|
+
body = dict_fold(map, body, (body, key, value) => {
|
|
803
|
+
if (!first) body = body + ", ";
|
|
804
|
+
first = false;
|
|
805
|
+
return body + "#(" + this.inspect(key) + ", " + this.inspect(value) + ")";
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
return body + "])";
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
#customType(record) {
|
|
812
|
+
const props = Object.keys(record)
|
|
813
|
+
.map((label) => {
|
|
814
|
+
const value = this.inspect(record[label]);
|
|
815
|
+
return isNaN(parseInt(label)) ? `${label}: ${value}` : value;
|
|
816
|
+
})
|
|
817
|
+
.join(", ");
|
|
818
|
+
return props
|
|
819
|
+
? `${record.constructor.name}(${props})`
|
|
820
|
+
: record.constructor.name;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
#list(list) {
|
|
824
|
+
if (List$isEmpty(list)) {
|
|
825
|
+
return "[]";
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
let char_out = 'charlist.from_string("';
|
|
829
|
+
let list_out = "[";
|
|
830
|
+
|
|
831
|
+
let current = list;
|
|
832
|
+
while (List$isNonEmpty(current)) {
|
|
833
|
+
let element = current.head;
|
|
834
|
+
current = current.tail;
|
|
835
|
+
|
|
836
|
+
if (list_out !== "[") {
|
|
837
|
+
list_out += ", ";
|
|
838
|
+
}
|
|
839
|
+
list_out += this.inspect(element);
|
|
840
|
+
|
|
841
|
+
if (char_out) {
|
|
842
|
+
if (Number.isInteger(element) && element >= 32 && element <= 126) {
|
|
843
|
+
char_out += String.fromCharCode(element);
|
|
844
|
+
} else {
|
|
845
|
+
char_out = null;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
if (char_out) {
|
|
851
|
+
return char_out + '")';
|
|
852
|
+
} else {
|
|
853
|
+
return list_out + "]";
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
#string(str) {
|
|
858
|
+
let new_str = '"';
|
|
859
|
+
for (let i = 0; i < str.length; i++) {
|
|
860
|
+
const char = str[i];
|
|
861
|
+
switch (char) {
|
|
862
|
+
case "\n":
|
|
863
|
+
new_str += "\\n";
|
|
864
|
+
break;
|
|
865
|
+
case "\r":
|
|
866
|
+
new_str += "\\r";
|
|
867
|
+
break;
|
|
868
|
+
case "\t":
|
|
869
|
+
new_str += "\\t";
|
|
870
|
+
break;
|
|
871
|
+
case "\f":
|
|
872
|
+
new_str += "\\f";
|
|
873
|
+
break;
|
|
874
|
+
case "\\":
|
|
875
|
+
new_str += "\\\\";
|
|
876
|
+
break;
|
|
877
|
+
case '"':
|
|
878
|
+
new_str += '\\"';
|
|
879
|
+
break;
|
|
880
|
+
default:
|
|
881
|
+
if (char < " " || (char > "~" && char < "\u{00A0}")) {
|
|
882
|
+
new_str +=
|
|
883
|
+
"\\u{" +
|
|
884
|
+
char.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0") +
|
|
885
|
+
"}";
|
|
886
|
+
} else {
|
|
887
|
+
new_str += char;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
new_str += '"';
|
|
892
|
+
return new_str;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
#utfCodepoint(codepoint) {
|
|
896
|
+
return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
#bit_array(bits) {
|
|
900
|
+
if (bits.bitSize === 0) {
|
|
901
|
+
return "<<>>";
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
let acc = "<<";
|
|
905
|
+
|
|
906
|
+
for (let i = 0; i < bits.byteSize - 1; i++) {
|
|
907
|
+
acc += bits.byteAt(i).toString();
|
|
908
|
+
acc += ", ";
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
if (bits.byteSize * 8 === bits.bitSize) {
|
|
912
|
+
acc += bits.byteAt(bits.byteSize - 1).toString();
|
|
913
|
+
} else {
|
|
914
|
+
const trailingBitsCount = bits.bitSize % 8;
|
|
915
|
+
acc += bits.byteAt(bits.byteSize - 1) >> (8 - trailingBitsCount);
|
|
916
|
+
acc += `:size(${trailingBitsCount})`;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
acc += ">>";
|
|
920
|
+
return acc;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
export function base16_encode(bit_array) {
|
|
925
|
+
const trailingBitsCount = bit_array.bitSize % 8;
|
|
926
|
+
|
|
927
|
+
let result = "";
|
|
928
|
+
|
|
929
|
+
for (let i = 0; i < bit_array.byteSize; i++) {
|
|
930
|
+
let byte = bit_array.byteAt(i);
|
|
931
|
+
|
|
932
|
+
if (i === bit_array.byteSize - 1 && trailingBitsCount !== 0) {
|
|
933
|
+
const unusedBitsCount = 8 - trailingBitsCount;
|
|
934
|
+
byte = (byte >> unusedBitsCount) << unusedBitsCount;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
result += byte.toString(16).padStart(2, "0").toUpperCase();
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
return result;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
export function base16_decode(string) {
|
|
944
|
+
const bytes = new Uint8Array(string.length / 2);
|
|
945
|
+
for (let i = 0; i < string.length; i += 2) {
|
|
946
|
+
const a = parseInt(string[i], 16);
|
|
947
|
+
const b = parseInt(string[i + 1], 16);
|
|
948
|
+
if (isNaN(a) || isNaN(b)) return Result$Error(Nil);
|
|
949
|
+
bytes[i / 2] = a * 16 + b;
|
|
950
|
+
}
|
|
951
|
+
return Result$Ok(new BitArray(bytes));
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
export function bit_array_to_int_and_size(bits) {
|
|
955
|
+
const trailingBitsCount = bits.bitSize % 8;
|
|
956
|
+
const unusedBitsCount = trailingBitsCount === 0 ? 0 : 8 - trailingBitsCount;
|
|
957
|
+
|
|
958
|
+
return [bits.byteAt(0) >> unusedBitsCount, bits.bitSize];
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
export function bit_array_starts_with(bits, prefix) {
|
|
962
|
+
if (prefix.bitSize > bits.bitSize) {
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
// Check any whole bytes
|
|
967
|
+
const byteCount = Math.trunc(prefix.bitSize / 8);
|
|
968
|
+
for (let i = 0; i < byteCount; i++) {
|
|
969
|
+
if (bits.byteAt(i) !== prefix.byteAt(i)) {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// Check any trailing bits at the end of the prefix
|
|
975
|
+
if (prefix.bitSize % 8 !== 0) {
|
|
976
|
+
const unusedBitsCount = 8 - (prefix.bitSize % 8);
|
|
977
|
+
if (
|
|
978
|
+
bits.byteAt(byteCount) >> unusedBitsCount !==
|
|
979
|
+
prefix.byteAt(byteCount) >> unusedBitsCount
|
|
980
|
+
) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
return true;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
export function log(x) {
|
|
989
|
+
// It is checked in Gleam that:
|
|
990
|
+
// - The input is strictly positive (x > 0)
|
|
991
|
+
// - This ensures that Math.log will never return NaN or -Infinity
|
|
992
|
+
// The function can thus safely pass the input to Math.log
|
|
993
|
+
// and a valid finite float will always be produced.
|
|
994
|
+
return Math.log(x);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
export function exp(x) {
|
|
998
|
+
return Math.exp(x);
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
export function list_to_array(list) {
|
|
1002
|
+
let current = list;
|
|
1003
|
+
let array = [];
|
|
1004
|
+
while (List$isNonEmpty(current)) {
|
|
1005
|
+
array.push(current.head);
|
|
1006
|
+
current = current.tail;
|
|
1007
|
+
}
|
|
1008
|
+
return array;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
export function index(data, key) {
|
|
1012
|
+
// Dictionaries and dictionary-like objects can be indexed
|
|
1013
|
+
if (data instanceof Dict) {
|
|
1014
|
+
const result = dict_get(data, key);
|
|
1015
|
+
return Result$Ok(result.isOk() ? new Some(result[0]) : new None());
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
if (data instanceof WeakMap || data instanceof Map) {
|
|
1019
|
+
const token = {};
|
|
1020
|
+
const entry = data.get(key, token);
|
|
1021
|
+
if (entry === token) return Result$Ok(new None());
|
|
1022
|
+
return Result$Ok(new Some(entry));
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
const key_is_int = Number.isInteger(key);
|
|
1026
|
+
|
|
1027
|
+
// Only elements 0-7 of lists can be indexed, negative indices are not allowed
|
|
1028
|
+
if (key_is_int && key >= 0 && key < 8 && isList(data)) {
|
|
1029
|
+
let i = 0;
|
|
1030
|
+
for (const value of data) {
|
|
1031
|
+
if (i === key) return Result$Ok(new Some(value));
|
|
1032
|
+
i++;
|
|
1033
|
+
}
|
|
1034
|
+
return Result$Error("Indexable");
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// Arrays and objects can be indexed
|
|
1038
|
+
if (
|
|
1039
|
+
(key_is_int && Array.isArray(data)) ||
|
|
1040
|
+
(data && typeof data === "object") ||
|
|
1041
|
+
(data && Object.getPrototypeOf(data) === Object.prototype)
|
|
1042
|
+
) {
|
|
1043
|
+
if (key in data) return Result$Ok(new Some(data[key]));
|
|
1044
|
+
return Result$Ok(new None());
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
return Result$Error(key_is_int ? "Indexable" : "Dict");
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
export function list(data, decode, pushPath, index, emptyList) {
|
|
1051
|
+
if (!(isList(data) || Array.isArray(data))) {
|
|
1052
|
+
const error = DecodeError$DecodeError("List", classify(data), emptyList);
|
|
1053
|
+
return [emptyList, arrayToList([error])];
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
const decoded = [];
|
|
1057
|
+
|
|
1058
|
+
for (const element of data) {
|
|
1059
|
+
const layer = decode(element);
|
|
1060
|
+
const [out, errors] = layer;
|
|
1061
|
+
|
|
1062
|
+
if (List$isNonEmpty(errors)) {
|
|
1063
|
+
const [_, errors] = pushPath(layer, index.toString());
|
|
1064
|
+
return [emptyList, errors];
|
|
1065
|
+
}
|
|
1066
|
+
decoded.push(out);
|
|
1067
|
+
index++;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
return [arrayToList(decoded), emptyList];
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
export function dict(data) {
|
|
1074
|
+
if (data instanceof Dict) {
|
|
1075
|
+
return Result$Ok(data);
|
|
1076
|
+
}
|
|
1077
|
+
if (data instanceof Map || data instanceof WeakMap) {
|
|
1078
|
+
return Result$Ok(dict_from_iterable(data));
|
|
1079
|
+
}
|
|
1080
|
+
if (data == null) {
|
|
1081
|
+
return Result$Error("Dict");
|
|
1082
|
+
}
|
|
1083
|
+
if (typeof data !== "object") {
|
|
1084
|
+
return Result$Error("Dict");
|
|
1085
|
+
}
|
|
1086
|
+
const proto = Object.getPrototypeOf(data);
|
|
1087
|
+
if (proto === Object.prototype || proto === null) {
|
|
1088
|
+
return Result$Ok(dict_from_iterable(Object.entries(data)));
|
|
1089
|
+
}
|
|
1090
|
+
return Result$Error("Dict");
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
export function bit_array(data) {
|
|
1094
|
+
if (data instanceof BitArray) return Result$Ok(data);
|
|
1095
|
+
if (data instanceof Uint8Array) return Result$Ok(new BitArray(data));
|
|
1096
|
+
return Result$Error(new BitArray(new Uint8Array()));
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
export function float(data) {
|
|
1100
|
+
if (typeof data === "number") return Result$Ok(data);
|
|
1101
|
+
return Result$Error(0.0);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
export function int(data) {
|
|
1105
|
+
if (Number.isInteger(data)) return Result$Ok(data);
|
|
1106
|
+
return Result$Error(0);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
export function string(data) {
|
|
1110
|
+
if (typeof data === "string") return Result$Ok(data);
|
|
1111
|
+
return Result$Error("");
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
export function is_null(data) {
|
|
1115
|
+
return data === null || data === undefined;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
function arrayToList(array) {
|
|
1119
|
+
let list = List$Empty();
|
|
1120
|
+
let i = array.length;
|
|
1121
|
+
while (i--) {
|
|
1122
|
+
list = List$NonEmpty(array[i], list);
|
|
1123
|
+
}
|
|
1124
|
+
return list;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
function isList(data) {
|
|
1128
|
+
return List$isEmpty(data) || List$isNonEmpty(data);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
function isResult(data) {
|
|
1132
|
+
return Result$isOk(data) || Result$isError(data);
|
|
1133
|
+
}
|