create-mendix-widget-gleam 2.0.14 → 2.0.16

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 (203) hide show
  1. package/README.md +1 -1
  2. package/package.json +5 -1
  3. package/src/index.mjs +32 -12
  4. package/template/gleam.toml +1 -1
  5. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache +0 -0
  6. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_inline +0 -0
  7. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache_meta +0 -0
  8. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache +0 -0
  9. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_inline +0 -0
  10. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_meta +0 -0
  11. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache +0 -0
  12. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_inline +0 -0
  13. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache_meta +0 -0
  14. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache +0 -0
  15. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_inline +0 -0
  16. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache_meta +0 -0
  17. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache +0 -0
  18. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_inline +0 -0
  19. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache_meta +0 -0
  20. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache +0 -0
  21. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_inline +0 -0
  22. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache_meta +0 -0
  23. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache +0 -0
  24. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_inline +0 -0
  25. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache_meta +0 -0
  26. package/tui/build/dev/javascript/etch/etch/command.mjs +479 -0
  27. package/tui/build/dev/javascript/etch/etch/cursor.mjs +164 -0
  28. package/tui/build/dev/javascript/etch/etch/event.mjs +2399 -0
  29. package/tui/build/dev/javascript/etch/etch/internal/consts.mjs +3 -0
  30. package/tui/build/dev/javascript/etch/etch/stdout.mjs +375 -0
  31. package/tui/build/dev/javascript/etch/etch/style.mjs +741 -0
  32. package/tui/build/dev/javascript/etch/etch/terminal.mjs +137 -0
  33. package/tui/build/dev/javascript/etch/gleam.mjs +1 -0
  34. package/tui/build/dev/javascript/etch/input/event_ffi.erl +73 -0
  35. package/tui/build/dev/javascript/etch/input/input_ffi.mjs +192 -0
  36. package/tui/build/dev/javascript/etch/input/signal_handler.erl +33 -0
  37. package/tui/build/dev/javascript/etch/terminal/terminal_ffi.erl +22 -0
  38. package/tui/build/dev/javascript/etch/terminal/terminal_ffi.mjs +37 -0
  39. package/tui/build/dev/javascript/etch/terminal/tty_state.erl +29 -0
  40. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache +0 -0
  41. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_inline +0 -0
  42. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache_meta +0 -0
  43. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache +0 -0
  44. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_inline +0 -0
  45. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta +0 -0
  46. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache +0 -0
  47. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_inline +0 -0
  48. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta +0 -0
  49. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache +0 -0
  50. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_inline +0 -0
  51. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta +0 -0
  52. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache +0 -0
  53. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_inline +0 -0
  54. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache_meta +0 -0
  55. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache +0 -0
  56. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_inline +0 -0
  57. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta +0 -0
  58. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache +0 -0
  59. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_inline +0 -0
  60. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache_meta +0 -0
  61. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/application.mjs +38 -0
  62. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/atom.mjs +2 -0
  63. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/charlist.mjs +1 -0
  64. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/node.mjs +12 -0
  65. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/port.mjs +1 -0
  66. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/process.mjs +161 -0
  67. package/tui/build/dev/javascript/gleam_erlang/gleam/erlang/reference.mjs +1 -0
  68. package/tui/build/dev/javascript/gleam_erlang/gleam.mjs +1 -0
  69. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@application.erl +43 -0
  70. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@atom.erl +94 -0
  71. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@charlist.erl +42 -0
  72. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@node.erl +80 -0
  73. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@port.erl +8 -0
  74. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@process.erl +868 -0
  75. package/tui/build/dev/javascript/gleam_erlang/gleam@erlang@reference.erl +21 -0
  76. package/tui/build/dev/javascript/gleam_erlang/gleam_erlang_ffi.erl +164 -0
  77. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache +0 -0
  78. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_inline +0 -0
  79. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache_meta +0 -0
  80. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache +0 -0
  81. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_inline +0 -0
  82. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache_meta +0 -0
  83. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache +0 -0
  84. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_inline +0 -0
  85. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache_meta +0 -0
  86. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/array.mjs +24 -0
  87. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/promise.mjs +105 -0
  88. package/tui/build/dev/javascript/gleam_javascript/gleam/javascript/symbol.mjs +7 -0
  89. package/tui/build/dev/javascript/gleam_javascript/gleam.mjs +1 -0
  90. package/tui/build/dev/javascript/gleam_javascript/gleam_javascript_ffi.mjs +133 -0
  91. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache +0 -0
  92. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_inline +0 -0
  93. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta +0 -0
  94. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache +0 -0
  95. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_inline +0 -0
  96. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta +0 -0
  97. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache +0 -0
  98. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_inline +0 -0
  99. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache_meta +0 -0
  100. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache +0 -0
  101. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_inline +0 -0
  102. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta +0 -0
  103. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache +0 -0
  104. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_inline +0 -0
  105. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta +0 -0
  106. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache +0 -0
  107. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_inline +0 -0
  108. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_meta +0 -0
  109. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache +0 -0
  110. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_inline +0 -0
  111. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta +0 -0
  112. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache +0 -0
  113. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_inline +0 -0
  114. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta +0 -0
  115. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache +0 -0
  116. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_inline +0 -0
  117. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta +0 -0
  118. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache +0 -0
  119. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_inline +0 -0
  120. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta +0 -0
  121. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache +0 -0
  122. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_inline +0 -0
  123. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta +0 -0
  124. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache +0 -0
  125. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_inline +0 -0
  126. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta +0 -0
  127. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache +0 -0
  128. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_inline +0 -0
  129. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta +0 -0
  130. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache +0 -0
  131. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_inline +0 -0
  132. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta +0 -0
  133. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache +0 -0
  134. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_inline +0 -0
  135. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta +0 -0
  136. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache +0 -0
  137. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_inline +0 -0
  138. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta +0 -0
  139. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache +0 -0
  140. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_inline +0 -0
  141. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta +0 -0
  142. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache +0 -0
  143. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_inline +0 -0
  144. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache_meta +0 -0
  145. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache +0 -0
  146. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_inline +0 -0
  147. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta +0 -0
  148. package/tui/build/dev/javascript/gleam_stdlib/dict.mjs +710 -0
  149. package/tui/build/dev/javascript/gleam_stdlib/gleam/bit_array.mjs +286 -0
  150. package/tui/build/dev/javascript/gleam_stdlib/gleam/bool.mjs +295 -0
  151. package/tui/build/dev/javascript/gleam_stdlib/gleam/bytes_tree.mjs +225 -0
  152. package/tui/build/dev/javascript/gleam_stdlib/gleam/dict.mjs +455 -0
  153. package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic/decode.mjs +993 -0
  154. package/tui/build/dev/javascript/gleam_stdlib/gleam/dynamic.mjs +35 -0
  155. package/tui/build/dev/javascript/gleam_stdlib/gleam/float.mjs +528 -0
  156. package/tui/build/dev/javascript/gleam_stdlib/gleam/function.mjs +6 -0
  157. package/tui/build/dev/javascript/gleam_stdlib/gleam/int.mjs +764 -0
  158. package/tui/build/dev/javascript/gleam_stdlib/gleam/io.mjs +8 -0
  159. package/tui/build/dev/javascript/gleam_stdlib/gleam/list.mjs +3063 -0
  160. package/tui/build/dev/javascript/gleam_stdlib/gleam/option.mjs +386 -0
  161. package/tui/build/dev/javascript/gleam_stdlib/gleam/order.mjs +166 -0
  162. package/tui/build/dev/javascript/gleam_stdlib/gleam/pair.mjs +96 -0
  163. package/tui/build/dev/javascript/gleam_stdlib/gleam/result.mjs +448 -0
  164. package/tui/build/dev/javascript/gleam_stdlib/gleam/set.mjs +413 -0
  165. package/tui/build/dev/javascript/gleam_stdlib/gleam/string.mjs +695 -0
  166. package/tui/build/dev/javascript/gleam_stdlib/gleam/string_tree.mjs +128 -0
  167. package/tui/build/dev/javascript/gleam_stdlib/gleam/uri.mjs +1151 -0
  168. package/tui/build/dev/javascript/gleam_stdlib/gleam.mjs +1 -0
  169. package/tui/build/dev/javascript/gleam_stdlib/gleam@bit_array.erl +347 -0
  170. package/tui/build/dev/javascript/gleam_stdlib/gleam@bool.erl +334 -0
  171. package/tui/build/dev/javascript/gleam_stdlib/gleam@bytes_tree.erl +211 -0
  172. package/tui/build/dev/javascript/gleam_stdlib/gleam@dict.erl +513 -0
  173. package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic.erl +105 -0
  174. package/tui/build/dev/javascript/gleam_stdlib/gleam@dynamic@decode.erl +1114 -0
  175. package/tui/build/dev/javascript/gleam_stdlib/gleam@float.erl +711 -0
  176. package/tui/build/dev/javascript/gleam_stdlib/gleam@function.erl +18 -0
  177. package/tui/build/dev/javascript/gleam_stdlib/gleam@int.erl +972 -0
  178. package/tui/build/dev/javascript/gleam_stdlib/gleam@io.erl +76 -0
  179. package/tui/build/dev/javascript/gleam_stdlib/gleam@list.erl +2735 -0
  180. package/tui/build/dev/javascript/gleam_stdlib/gleam@option.erl +381 -0
  181. package/tui/build/dev/javascript/gleam_stdlib/gleam@order.erl +188 -0
  182. package/tui/build/dev/javascript/gleam_stdlib/gleam@pair.erl +104 -0
  183. package/tui/build/dev/javascript/gleam_stdlib/gleam@result.erl +500 -0
  184. package/tui/build/dev/javascript/gleam_stdlib/gleam@set.erl +430 -0
  185. package/tui/build/dev/javascript/gleam_stdlib/gleam@string.erl +964 -0
  186. package/tui/build/dev/javascript/gleam_stdlib/gleam@string_tree.erl +202 -0
  187. package/tui/build/dev/javascript/gleam_stdlib/gleam@uri.erl +1042 -0
  188. package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.erl +534 -0
  189. package/tui/build/dev/javascript/gleam_stdlib/gleam_stdlib.mjs +1133 -0
  190. package/tui/build/dev/javascript/gleam_version +1 -0
  191. package/tui/build/dev/javascript/prelude.mjs +1575 -0
  192. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache +0 -0
  193. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_inline +0 -0
  194. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_meta +0 -0
  195. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_warnings +0 -0
  196. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache +0 -0
  197. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_inline +0 -0
  198. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_meta +0 -0
  199. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_warnings +0 -0
  200. package/tui/build/dev/javascript/tui/gleam.mjs +1 -0
  201. package/tui/build/dev/javascript/tui/tui/prompt.mjs +521 -0
  202. package/tui/build/dev/javascript/tui/tui.mjs +334 -0
  203. package/tui/build/dev/javascript/tui/tui_ffi.mjs +32 -0
@@ -0,0 +1,710 @@
1
+ /**
2
+ * This file uses jsdoc to annotate types.
3
+ * These types can be checked using the typescript compiler with "checkjs" option.
4
+ */
5
+
6
+ import { isEqual, Result$Error, Result$Ok } from "./gleam.mjs";
7
+
8
+ // -- HASH --------------------------------------------------------------------
9
+
10
+ const referenceMap = /* @__PURE__ */ new WeakMap();
11
+ const tempDataView = /* @__PURE__ */ new DataView(
12
+ /* @__PURE__ */ new ArrayBuffer(8),
13
+ );
14
+ let referenceUID = 0;
15
+ /**
16
+ * hash the object by reference using a weak map and incrementing uid
17
+ * @param {any} o
18
+ * @returns {number}
19
+ */
20
+ function hashByReference(o) {
21
+ const known = referenceMap.get(o);
22
+ if (known !== undefined) {
23
+ return known;
24
+ }
25
+ const hash = referenceUID++;
26
+ if (referenceUID === 0x7fffffff) {
27
+ referenceUID = 0;
28
+ }
29
+ referenceMap.set(o, hash);
30
+ return hash;
31
+ }
32
+
33
+ /**
34
+ * merge two hashes in an order sensitive way
35
+ * @param {number} a
36
+ * @param {number} b
37
+ * @returns {number}
38
+ */
39
+ function hashMerge(a, b) {
40
+ return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0;
41
+ }
42
+
43
+ /**
44
+ * standard string hash popularised by Java
45
+ * @param {string} s
46
+ * @returns {number}
47
+ */
48
+ function hashString(s) {
49
+ let hash = 0;
50
+ const len = s.length;
51
+ for (let i = 0; i < len; i++) {
52
+ hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0;
53
+ }
54
+ return hash;
55
+ }
56
+
57
+ /**
58
+ * hash a number by converting to two integers and do some jumbling
59
+ * @param {number} n
60
+ * @returns {number}
61
+ */
62
+ function hashNumber(n) {
63
+ tempDataView.setFloat64(0, n);
64
+ const i = tempDataView.getInt32(0);
65
+ const j = tempDataView.getInt32(4);
66
+ return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j;
67
+ }
68
+
69
+ /**
70
+ * hash a BigInt by converting it to a string and hashing that
71
+ * @param {BigInt} n
72
+ * @returns {number}
73
+ */
74
+ function hashBigInt(n) {
75
+ return hashString(n.toString());
76
+ }
77
+
78
+ /**
79
+ * hash any js object
80
+ * @param {any} o
81
+ * @returns {number}
82
+ */
83
+ function hashObject(o) {
84
+ const proto = Object.getPrototypeOf(o);
85
+ if (proto !== null && typeof proto.hashCode === "function") {
86
+ try {
87
+ const code = o.hashCode(o);
88
+ if (typeof code === "number") {
89
+ return code;
90
+ }
91
+ } catch {}
92
+ }
93
+ if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) {
94
+ return hashByReference(o);
95
+ }
96
+ if (o instanceof Date) {
97
+ return hashNumber(o.getTime());
98
+ }
99
+ let h = 0;
100
+ if (o instanceof ArrayBuffer) {
101
+ o = new Uint8Array(o);
102
+ }
103
+ if (Array.isArray(o) || o instanceof Uint8Array) {
104
+ for (let i = 0; i < o.length; i++) {
105
+ h = (Math.imul(31, h) + getHash(o[i])) | 0;
106
+ }
107
+ } else if (o instanceof Set) {
108
+ o.forEach((v) => {
109
+ h = (h + getHash(v)) | 0;
110
+ });
111
+ } else if (o instanceof Map) {
112
+ o.forEach((v, k) => {
113
+ h = (h + hashMerge(getHash(v), getHash(k))) | 0;
114
+ });
115
+ } else {
116
+ const keys = Object.keys(o);
117
+ for (let i = 0; i < keys.length; i++) {
118
+ const k = keys[i];
119
+ const v = o[k];
120
+ h = (h + hashMerge(getHash(v), hashString(k))) | 0;
121
+ }
122
+ }
123
+ return h;
124
+ }
125
+
126
+ /**
127
+ * hash any js value
128
+ * @param {any} u
129
+ * @returns {number}
130
+ */
131
+ export function getHash(u) {
132
+ if (u === null) return 0x42108422;
133
+ if (u === undefined) return 0x42108423;
134
+ if (u === true) return 0x42108421;
135
+ if (u === false) return 0x42108420;
136
+ switch (typeof u) {
137
+ case "number":
138
+ return hashNumber(u);
139
+ case "string":
140
+ return hashString(u);
141
+ case "bigint":
142
+ return hashBigInt(u);
143
+ case "object":
144
+ return hashObject(u);
145
+ case "symbol":
146
+ return hashByReference(u);
147
+ case "function":
148
+ return hashByReference(u);
149
+ default:
150
+ return 0; // should be unreachable
151
+ }
152
+ }
153
+
154
+ // -- DICT --------------------------------------------------------------------
155
+
156
+ /**
157
+ * An implementation of the CHAMP data structure, an optimised HAMT.
158
+ *
159
+ * See: M. J. Steindorfer, J.J. Vinju (2015). Optimizing Hash-Array Mapped Tries for
160
+ Fast and Lean Immutable JVM Collections. Available: https://michael.steindorfer.name/publications/oopsla15.pdf
161
+ */
162
+ export default class Dict {
163
+ constructor(size, root) {
164
+ this.size = size;
165
+ this.root = root;
166
+ }
167
+ }
168
+
169
+ /// The power-of-2 branching factor for the dict. For example, a value of `5` indicates a 32-ary tree.
170
+ const bits = 5;
171
+ const mask = (1 << bits) - 1;
172
+
173
+ /// This symbol is used internally to avoid constructing results.
174
+ const noElementMarker = Symbol();
175
+
176
+ /// This symbol is used to store the "generation" on a node.
177
+ /// Using a symbol makes the property not enumerable, which means the generation
178
+ /// will be ignored during equality checks.
179
+ const generationKey = Symbol();
180
+
181
+ // Some commonly used constants throughout the code.
182
+ const emptyNode = /* @__PURE__ */ newNode(0);
183
+ const emptyDict = /* @__PURE__ */ new Dict(0, emptyNode);
184
+ const errorNil = /* @__PURE__ */ Result$Error(undefined);
185
+
186
+ function makeNode(generation, datamap, nodemap, data) {
187
+ // The order of fields is important, as they define the order `isEqual` will
188
+ // compare our fields. Putting the bitmaps first means that equality can
189
+ // early-out if the bitmaps are not equal.
190
+ return {
191
+ // A node is a high-arity (32 in practice) hybrid tree node.
192
+ // Hybrid means that it stores data directly as well as pointers to child nodes.
193
+ //
194
+ // Each node contains 2 bitmaps:
195
+ // - The datamap has a bit set if that slot in the node contains direct data
196
+ // - The nodemap has a bit set if that slot in the node contains another node.
197
+ //
198
+ // Both are exclusive to on another, so datamap & nodemap == 0.
199
+ //
200
+ // Every key/hash value directly correlates to a specific bit by using a trie
201
+ // suffix (least significant bits first) encoding.
202
+ // For example, if the last 5 bits of the hash are 1101, the bit to check for
203
+ // that value is the 13th bit.
204
+ datamap,
205
+ nodemap,
206
+ // The slots itself are stored in a single contiguous array that contains
207
+ // both direct k/v-pairs and child nodes.
208
+ //
209
+ // The direct children come first, followed by the child nodes in _reverse order_:
210
+ //
211
+ // 7654321
212
+ // datamap: 1000100
213
+ // nodemap: 10011
214
+ // data: [key3, value3, key7, value7, child5, child2, child1]
215
+ // -------------------------> <---------------------
216
+ // datamap nodemap
217
+ //
218
+ // Every `1` bit in the datamap corresponds to a pair of [key, value] entries,
219
+ // and every `1` bit in the nodemap corresponds to a child node entry.
220
+ //
221
+ // Children are stored in reverse order to avoid having to store or calculate an
222
+ // "offset" value to skip over the direct children.
223
+ data,
224
+ // The generation is used to track which nodes need to be copied during transient updates.
225
+ // Using a symbol here makes `isEqual` ignore this field.
226
+ [generationKey]: generation,
227
+ };
228
+ }
229
+
230
+ function newNode(generation) {
231
+ return makeNode(generation, 0, 0, []);
232
+ }
233
+
234
+ /**
235
+ * Copies a node and its data array if it's from another generation, making it safe
236
+ * to mutate the node.
237
+ */
238
+ function copyNode(node, generation) {
239
+ if (node[generationKey] === generation) {
240
+ return node;
241
+ }
242
+
243
+ const newData = node.data.slice(0);
244
+ return makeNode(generation, node.datamap, node.nodemap, newData);
245
+ }
246
+
247
+ /**
248
+ * Copies a node if needed and sets a new value.
249
+ */
250
+ function copyAndSet(node, generation, idx, val) {
251
+ if (node.data[idx] === val) {
252
+ return node;
253
+ }
254
+
255
+ // Using copyNode is faster than a specialised implementation.
256
+ node = copyNode(node, generation);
257
+ node.data[idx] = val;
258
+ return node;
259
+ }
260
+
261
+ /**
262
+ * Copies a node if needed, and then inserts a new key-value pair.
263
+ */
264
+ function copyAndInsertPair(node, generation, bit, idx, key, val) {
265
+ const data = node.data;
266
+ const length = data.length;
267
+
268
+ // the fastest way to insert a pair is to always copy.
269
+ const newData = new Array(length + 2);
270
+
271
+ let readIndex = 0;
272
+ let writeIndex = 0;
273
+
274
+ while (readIndex < idx) newData[writeIndex++] = data[readIndex++];
275
+ newData[writeIndex++] = key;
276
+ newData[writeIndex++] = val;
277
+ while (readIndex < length) newData[writeIndex++] = data[readIndex++];
278
+
279
+ return makeNode(generation, node.datamap | bit, node.nodemap, newData);
280
+ }
281
+
282
+ function copyAndRemovePair(node, generation, bit, idx) {
283
+ node = copyNode(node, generation);
284
+
285
+ const data = node.data;
286
+ const length = data.length;
287
+ for (let w = idx, r = idx + 2; r < length; ++r, ++w) {
288
+ data[w] = data[r];
289
+ }
290
+ data.pop();
291
+ data.pop();
292
+
293
+ node.datamap ^= bit;
294
+ return node;
295
+ }
296
+
297
+ export function make() {
298
+ return emptyDict;
299
+ }
300
+
301
+ export function from(iterable) {
302
+ let transient = toTransient(emptyDict);
303
+ for (const [key, value] of iterable) {
304
+ transient = destructiveTransientInsert(key, value, transient);
305
+ }
306
+ return fromTransient(transient);
307
+ }
308
+
309
+ export function size(dict) {
310
+ return dict.size;
311
+ }
312
+
313
+ export function get(dict, key) {
314
+ const result = lookup(dict.root, key, getHash(key));
315
+ return result !== noElementMarker ? Result$Ok(result) : errorNil;
316
+ }
317
+
318
+ export function has(dict, key) {
319
+ return lookup(dict.root, key, getHash(key)) !== noElementMarker;
320
+ }
321
+
322
+ function lookup(node, key, hash) {
323
+ for (let shift = 0; shift < 32; shift += bits) {
324
+ const data = node.data;
325
+ const bit = hashbit(hash, shift);
326
+
327
+ if (node.nodemap & bit) {
328
+ // we found our hash inside the nodemap, so we can continue our search there.
329
+ node = data[data.length - 1 - index(node.nodemap, bit)];
330
+ } else if (node.datamap & bit) {
331
+ // we store this hash directly!
332
+ //
333
+ // this also means that there are no other values with the same
334
+ // hash prefix in this dict.
335
+ //
336
+ // We still need to check if the key matches, but if it does we know for
337
+ // sure that this is the correct value, and if it doesn't that we don't
338
+ // contain the value in question.
339
+ const dataidx = Math.imul(index(node.datamap, bit), 2);
340
+ return isEqual(key, data[dataidx]) ? data[dataidx + 1] : noElementMarker;
341
+ } else {
342
+ // if the hash bit is not set in neither bitmaps, we immediately know that
343
+ // this key cannot be inside this dict.
344
+ return noElementMarker;
345
+ }
346
+ }
347
+
348
+ // our shift has exceeded 32 bits. Everything that follows is
349
+ // implicitely an overflow node and only contains direct children.
350
+ const overflow = node.data;
351
+ for (let i = 0; i < overflow.length; i += 2) {
352
+ if (isEqual(key, overflow[i])) {
353
+ return overflow[i + 1];
354
+ }
355
+ }
356
+
357
+ return noElementMarker;
358
+ }
359
+
360
+ /**
361
+ * We use "transient" values to allow for safer internal mutations of the data
362
+ * structure. This is an optimisation only. No mutable API is exposed to the user.
363
+ *
364
+ * Transients are to be treated as having a linear (single-use, think rust) type.
365
+ * A transient value becomes invalid as soon as it's passed to one of the functions.
366
+ *
367
+ * Internally, we track a "generation" value on each node. If the generation
368
+ * doesn't match the one for the current transient, we have to copy - the node
369
+ * could still be referenced by another dict instance!
370
+ * After that, no other references than the transient one exists, so it's safe
371
+ * to mutate in place.
372
+ */
373
+ export function toTransient(dict) {
374
+ return {
375
+ generation: nextGeneration(dict),
376
+ root: dict.root,
377
+ size: dict.size,
378
+ dict: dict,
379
+ };
380
+ }
381
+
382
+ /**
383
+ * Consume a transient, producing a normal Dict again.
384
+ */
385
+ export function fromTransient(transient) {
386
+ if (transient.root === transient.dict.root) {
387
+ return transient.dict;
388
+ }
389
+
390
+ return new Dict(transient.size, transient.root);
391
+ }
392
+
393
+ /**
394
+ * Find and allocate the next generation id.
395
+ *
396
+ * @template K,V
397
+ * @param {Dict<K,V>} dict
398
+ * @returns {number}
399
+ */
400
+ function nextGeneration(dict) {
401
+ const root = dict.root;
402
+ if (root[generationKey] < Number.MAX_SAFE_INTEGER) {
403
+ return root[generationKey] + 1;
404
+ }
405
+
406
+ // we have reached MAX_SAFE_INTEGER generations -
407
+ // at this point, we have to walk the dictionary once to reset the counter
408
+ // on every node. This is safe since it's part of the contract for transient
409
+ // that only one of them exists at any given time.
410
+ //
411
+ const queue = [root];
412
+ while (queue.length) {
413
+ // order doesn't matter, so we can use push/pop for faster array usage.
414
+ const node = queue.pop();
415
+
416
+ // reset the generation to 0
417
+ node[generationKey] = 0;
418
+
419
+ // queue all other referenced nodes
420
+ // We need to query the length from the nodemap, as we don't know if this
421
+ // is an overflow node or not! if it is, it will never have datamap set!
422
+ const nodeStart = data.length - popcount(node.nodemap);
423
+ for (let i = nodeStart; i < node.data.length; ++i) {
424
+ queue.push(node.data[i]);
425
+ }
426
+ }
427
+
428
+ return 1;
429
+ }
430
+
431
+ /// Insert is the second-most performance-sensitive operation.
432
+ /// We use a global "transient" value here to avoid doing a memory allocation.
433
+ const globalTransient = /* @__PURE__ */ toTransient(emptyDict);
434
+
435
+ export function insert(dict, key, value) {
436
+ globalTransient.generation = nextGeneration(dict);
437
+ globalTransient.size = dict.size;
438
+
439
+ const hash = getHash(key);
440
+ const root = insertIntoNode(globalTransient, dict.root, key, value, hash, 0);
441
+ if (root === dict.root) {
442
+ return dict;
443
+ }
444
+
445
+ return new Dict(globalTransient.size, root);
446
+ }
447
+
448
+ /**
449
+ * Consume a transient, writing a new key/value pair into the dictionary it
450
+ * represents. If the key already exists, it will be overwritten.
451
+ *
452
+ * Returns a new transient.
453
+ */
454
+ export function destructiveTransientInsert(key, value, transient) {
455
+ const hash = getHash(key);
456
+ transient.root = insertIntoNode(transient, transient.root, key, value, hash, 0);
457
+ return transient;
458
+ }
459
+
460
+ /**
461
+ * Consume a transient, writing a new key/value pair if the key doesn't exist or updating
462
+ * the existing value with a function if it does.
463
+ *
464
+ * Returns a new transient.
465
+ */
466
+ export function destructiveTransientUpdateWith(key, fun, value, transient) {
467
+ const hash = getHash(key);
468
+
469
+ const existing = lookup(transient.root, key, hash);
470
+ if (existing !== noElementMarker) {
471
+ value = fun(existing);
472
+ }
473
+ transient.root = insertIntoNode(transient, transient.root, key, value, hash, 0);
474
+ return transient;
475
+ }
476
+
477
+ function insertIntoNode(transient, node, key, value, hash, shift) {
478
+ const data = node.data;
479
+ const generation = transient.generation;
480
+
481
+ // 1. Overflow Node
482
+ // overflow nodes only contain key/value-pairs. we walk the data linearly trying to find a match.
483
+ if (shift > 32) {
484
+ for (let i = 0; i < data.length; i += 2) {
485
+ if (isEqual(key, data[i])) {
486
+ return copyAndSet(node, generation, i + 1, value);
487
+ }
488
+ }
489
+
490
+ transient.size += 1;
491
+ return copyAndInsertPair(node, generation, 0, data.length, key, value);
492
+ }
493
+
494
+ const bit = hashbit(hash, shift);
495
+
496
+ // 2. Child Node
497
+ // We have to check first if there is already a child node we have to traverse to.
498
+ if (node.nodemap & bit) {
499
+ const nodeidx = data.length - 1 - index(node.nodemap, bit);
500
+
501
+ let child = data[nodeidx];
502
+ child = insertIntoNode(transient, child, key, value, hash, shift + bits);
503
+ return copyAndSet(node, generation, nodeidx, child);
504
+ }
505
+
506
+ // 3. New Data Node
507
+ // No child node and no data node exists yet, so we can potentially just insert a new value.
508
+ const dataidx = Math.imul(index(node.datamap, bit), 2);
509
+ if ((node.datamap & bit) === 0) {
510
+ transient.size += 1;
511
+ return copyAndInsertPair(node, generation, bit, dataidx, key, value);
512
+ }
513
+
514
+ // 4. Existing Data Node
515
+ // We have a match that we can update, or remove.
516
+ if (isEqual(key, data[dataidx])) {
517
+ return copyAndSet(node, generation, dataidx + 1, value);
518
+ }
519
+
520
+ // 5. Collision
521
+ // There is no child node, but a data node with the same hash, but with a different key.
522
+ // To resolve this, we push both nodes down one level.
523
+ const childShift = shift + bits;
524
+
525
+ let child = emptyNode;
526
+ child = insertIntoNode(transient, child, key, value, hash, childShift);
527
+
528
+ const key2 = data[dataidx];
529
+ const value2 = data[dataidx + 1];
530
+ const hash2 = getHash(key2);
531
+ child = insertIntoNode(transient, child, key2, value2, hash2, childShift);
532
+
533
+ // we inserted 2 elements, but implicitely deleted the one we pushed down from the datamap.
534
+ transient.size -= 1;
535
+
536
+ // remove the old data pair, and insert the new child node.
537
+ const length = data.length;
538
+ const nodeidx = length - 1 - index(node.nodemap, bit);
539
+
540
+ // writing these loops in javascript instead of a combination of splices
541
+ // turns out to be faster. Copying always turned out to be faster.
542
+ const newData = new Array(length - 1);
543
+
544
+ let readIndex = 0;
545
+ let writeIndex = 0;
546
+
547
+ // [0..dataidx, skip 2 elements, ..nodeidx, newChild, ..rest]
548
+ while (readIndex < dataidx) newData[writeIndex++] = data[readIndex++];
549
+ readIndex += 2;
550
+ while (readIndex <= nodeidx) newData[writeIndex++] = data[readIndex++];
551
+ newData[writeIndex++] = child;
552
+ while (readIndex < length) newData[writeIndex++] = data[readIndex++];
553
+
554
+ return makeNode(generation, node.datamap ^ bit, node.nodemap | bit, newData);
555
+ }
556
+
557
+ /**
558
+ * Consume a transient, removing a key if it exists.
559
+ * Returns a new transient.
560
+ */
561
+ export function destructiveTransientDelete(key, transient) {
562
+ const hash = getHash(key);
563
+ transient.root = deleteFromNode(transient, transient.root, key, hash, 0);
564
+ return transient;
565
+ }
566
+
567
+ function deleteFromNode(transient, node, key, hash, shift) {
568
+ const data = node.data;
569
+ const generation = transient.generation;
570
+
571
+ // 1. Overflow Node
572
+ // overflow nodes only contain key/value-pairs. we walk the data linearly trying to find a match.
573
+ if (shift > 32) {
574
+ for (let i = 0; i < data.length; i += 2) {
575
+ if (isEqual(key, data[i])) {
576
+ transient.size -= 1;
577
+ return copyAndRemovePair(node, generation, 0, i);
578
+ }
579
+ }
580
+
581
+ return node;
582
+ }
583
+
584
+ const bit = hashbit(hash, shift);
585
+ const dataidx = Math.imul(index(node.datamap, bit), 2);
586
+
587
+ // 2. Child Node
588
+ // We have to check first if there is already a child node we have to traverse to.
589
+ if ((node.nodemap & bit) !== 0) {
590
+ const nodeidx = data.length - 1 - index(node.nodemap, bit);
591
+
592
+ let child = data[nodeidx];
593
+ child = deleteFromNode(transient, child, key, hash, shift + bits);
594
+
595
+ // the node did change, so let's copy to incorporate that change.
596
+ if (child.nodemap !== 0 || child.data.length > 2) {
597
+ return copyAndSet(node, generation, nodeidx, child);
598
+ }
599
+
600
+ // this node only has a single data (k/v-pair) child.
601
+ // to restore the CHAMP invariant, we "pull" that pair up into ourselves.
602
+ // this ensures that every tree stays in its single optimal representation,
603
+ // and allows dicts to be structurally compared.
604
+ const length = data.length;
605
+ const newData = new Array(length + 1);
606
+
607
+ let readIndex = 0;
608
+ let writeIndex = 0;
609
+
610
+ while (readIndex < dataidx) newData[writeIndex++] = data[readIndex++];
611
+ newData[writeIndex++] = child.data[0];
612
+ newData[writeIndex++] = child.data[1];
613
+ while (readIndex < nodeidx) newData[writeIndex++] = data[readIndex++];
614
+ readIndex++;
615
+ while (readIndex < length) newData[writeIndex++] = data[readIndex++];
616
+
617
+ return makeNode(generation, node.datamap | bit, node.nodemap ^ bit, newData);
618
+ }
619
+
620
+ // 3. Data Node
621
+ // There is no data entry here, or it is a prefix for a different key
622
+ if ((node.datamap & bit) === 0 || !isEqual(key, data[dataidx])) {
623
+ return node;
624
+ }
625
+
626
+ // we found a data entry that we can delete.
627
+ transient.size -= 1;
628
+ return copyAndRemovePair(node, generation, bit, dataidx);
629
+ }
630
+
631
+ export function map(dict, fun) {
632
+ // map can never modify the structure, so we can walk the dictionary directly,
633
+ // but still move to a new generation to make sure we get a new copy of every node.
634
+ const generation = nextGeneration(dict);
635
+ const root = copyNode(dict.root, generation);
636
+ const queue = [root];
637
+
638
+ while (queue.length) {
639
+ // order doesn't matter, so we can use push/pop for faster array usage.
640
+ const node = queue.pop();
641
+ const data = node.data;
642
+ // every node contains popcount(datamap) direct entries
643
+ // We need to query the length from the nodemap, as we don't know if this
644
+ // is an overflow node or not! if it is, it will never have datamap set!
645
+ const edgesStart = data.length - popcount(node.nodemap);
646
+ for (let i = 0; i < edgesStart; i += 2) {
647
+ // we copied the node while queueing it, so direct mutation here is safe.
648
+ data[i + 1] = fun(data[i], data[i + 1]);
649
+ }
650
+ // the remaining entries are other nodes we can queue
651
+ for (let i = edgesStart; i < data.length; ++i) {
652
+ // copy the node first to make it safe to mutate
653
+ data[i] = copyNode(data[i], generation);
654
+ queue.push(data[i]);
655
+ }
656
+ }
657
+
658
+ return new Dict(dict.size, root);
659
+ }
660
+
661
+ export function fold(dict, state, fun) {
662
+ const queue = [dict.root];
663
+
664
+ while (queue.length) {
665
+ // order doesn't matter, so we can use push/pop for faster array usage.
666
+ const node = queue.pop();
667
+ const data = node.data;
668
+ // every node contains popcount(datamap) direct entries
669
+ // We need to query the length from the nodemap, as we don't know if this
670
+ // is an overflow node or not! if it is, it will never have datamap set!
671
+ const edgesStart = data.length - popcount(node.nodemap);
672
+ for (let i = 0; i < edgesStart; i += 2) {
673
+ state = fun(state, data[i], data[i + 1]);
674
+ }
675
+ // the remaining entries are child nodes we can queue.
676
+ for (let i = edgesStart; i < data.length; ++i) {
677
+ queue.push(data[i]);
678
+ }
679
+ }
680
+
681
+ return state;
682
+ }
683
+
684
+ /**
685
+ * How many `1` bits are set in a 32-bit integer.
686
+ */
687
+ function popcount(n) {
688
+ n -= (n >>> 1) & 0x55555555;
689
+ n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
690
+ return Math.imul((n + (n >>> 4)) & 0x0f0f0f0f, 0x01010101) >>> 24;
691
+ }
692
+
693
+ /**
694
+ * Given a population bitmap and a bit selected from that map, returns
695
+ * how many less significant 1 bits there are.
696
+ *
697
+ * For example, index(10101, 100) returns 1, since there is a single less
698
+ * significant `1` bit. This translates to the 0-based "index" of that bit.
699
+ */
700
+ function index(bitmap, bit) {
701
+ return popcount(bitmap & (bit - 1));
702
+ }
703
+
704
+ /**
705
+ * Extracts a single slice of the hash, and returns a bitmask for the resulting value.
706
+ * For example, if the slice returns 5, this function returns 10000 = 1 << 5.
707
+ */
708
+ function hashbit(hash, shift) {
709
+ return 1 << ((hash >>> shift) & mask);
710
+ }